cedec 2016 metal と vulkan を用いた水彩画レンダリング技法の紹介

114
Copyright Drecom Co., Ltd. All Rights Reserved. 1 Metal と Vulkan をいた 彩画レンダリング技法の紹介 次世代のモバイルグラフィックスは NonPhotorealistic Rendering へと移する 株式会社ドリコム 増野 健 川上 知成

Upload: drecom-co-ltd

Post on 15-Apr-2017

2.739 views

Category:

Engineering


5 download

TRANSCRIPT

Page 1: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 1

Metal と Vulkan を用いた水彩画レンダリング技法の紹介

次世代のモバイルグラフィックスは Non-‐‑‒Photorealistic Rendering へと移行行する

株式会社ドリコム 増野 健人川上 知成

Copyright Drecom Co Ltd All Rights Reserved 2

講演者紹介

川上 知成 -‐‑‒ 進行行株式会社ドリコム プログラムマネジメント室サーバーサイドエンジニアPMを担当し現在は複数のプロジェクトに関与CEDEC2014 2015登壇

増野 健人 -‐‑‒ メインスピーカー株式会社ドリコム ゲームプロダクト部コンシューマゲーム会社にてグラフィックスシステムやシェーダー開発に携わるドリコム入社後は3Dシェーダー技術のスキルボトムアップの活動を行行う

本日の発表について

Copyright Drecom Co Ltd All Rights Reserved 3

Vulkan and the Vulkan logo are trademarks of the Khronos Group IncOpenGL is a registered trademark and the OpenGL ES logo is a trademark of Silicon Graphics Inc used by permission by KhronosSPIR and the SPIR logo are trademarks of the Khronos Group IncApple Mac iMac MacBook iPhone Xcode macOS Metal and OS X are trademarks of Apple Inc registered in the US and other countriesiOS is a trademark or registered trademark of Cisco in the US and other countries and is used under licenseAndroidtradeDirectXregFlowMap Painter (c)2012 Teck Lee Tan wwwteckArtistcom

Copyrights

Copyright Drecom Co Ltd All Rights Reserved 4

ゲームエンジンと要素技術基礎技術

はじめに

要素技術基礎技術を見見る理理由bull 対象事象の原理理原則を押さえるrarr比較対象や比較すべきポイントを選定出来評価が可能bull 時代に乗るrarr市場発表研究発見見などの各段階で見見極め必要な技術を取捨選択

Copyright Drecom Co Ltd All Rights Reserved 5

bull 近年年のモバイルグラフィックスbull グラフィックスAPI のパラダイムシフトbull Low-‐‑‒Overhead Low-‐‑‒Level プログラミングbull Non-‐‑‒Photorealistic Rendering における水彩画表現bull まとめ質疑応答

セッションの内容

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 2: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 2

講演者紹介

川上 知成 -‐‑‒ 進行行株式会社ドリコム プログラムマネジメント室サーバーサイドエンジニアPMを担当し現在は複数のプロジェクトに関与CEDEC2014 2015登壇

増野 健人 -‐‑‒ メインスピーカー株式会社ドリコム ゲームプロダクト部コンシューマゲーム会社にてグラフィックスシステムやシェーダー開発に携わるドリコム入社後は3Dシェーダー技術のスキルボトムアップの活動を行行う

本日の発表について

Copyright Drecom Co Ltd All Rights Reserved 3

Vulkan and the Vulkan logo are trademarks of the Khronos Group IncOpenGL is a registered trademark and the OpenGL ES logo is a trademark of Silicon Graphics Inc used by permission by KhronosSPIR and the SPIR logo are trademarks of the Khronos Group IncApple Mac iMac MacBook iPhone Xcode macOS Metal and OS X are trademarks of Apple Inc registered in the US and other countriesiOS is a trademark or registered trademark of Cisco in the US and other countries and is used under licenseAndroidtradeDirectXregFlowMap Painter (c)2012 Teck Lee Tan wwwteckArtistcom

Copyrights

Copyright Drecom Co Ltd All Rights Reserved 4

ゲームエンジンと要素技術基礎技術

はじめに

要素技術基礎技術を見見る理理由bull 対象事象の原理理原則を押さえるrarr比較対象や比較すべきポイントを選定出来評価が可能bull 時代に乗るrarr市場発表研究発見見などの各段階で見見極め必要な技術を取捨選択

Copyright Drecom Co Ltd All Rights Reserved 5

bull 近年年のモバイルグラフィックスbull グラフィックスAPI のパラダイムシフトbull Low-‐‑‒Overhead Low-‐‑‒Level プログラミングbull Non-‐‑‒Photorealistic Rendering における水彩画表現bull まとめ質疑応答

セッションの内容

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 3: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 3

Vulkan and the Vulkan logo are trademarks of the Khronos Group IncOpenGL is a registered trademark and the OpenGL ES logo is a trademark of Silicon Graphics Inc used by permission by KhronosSPIR and the SPIR logo are trademarks of the Khronos Group IncApple Mac iMac MacBook iPhone Xcode macOS Metal and OS X are trademarks of Apple Inc registered in the US and other countriesiOS is a trademark or registered trademark of Cisco in the US and other countries and is used under licenseAndroidtradeDirectXregFlowMap Painter (c)2012 Teck Lee Tan wwwteckArtistcom

Copyrights

Copyright Drecom Co Ltd All Rights Reserved 4

ゲームエンジンと要素技術基礎技術

はじめに

要素技術基礎技術を見見る理理由bull 対象事象の原理理原則を押さえるrarr比較対象や比較すべきポイントを選定出来評価が可能bull 時代に乗るrarr市場発表研究発見見などの各段階で見見極め必要な技術を取捨選択

Copyright Drecom Co Ltd All Rights Reserved 5

bull 近年年のモバイルグラフィックスbull グラフィックスAPI のパラダイムシフトbull Low-‐‑‒Overhead Low-‐‑‒Level プログラミングbull Non-‐‑‒Photorealistic Rendering における水彩画表現bull まとめ質疑応答

セッションの内容

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 4: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 4

ゲームエンジンと要素技術基礎技術

はじめに

要素技術基礎技術を見見る理理由bull 対象事象の原理理原則を押さえるrarr比較対象や比較すべきポイントを選定出来評価が可能bull 時代に乗るrarr市場発表研究発見見などの各段階で見見極め必要な技術を取捨選択

Copyright Drecom Co Ltd All Rights Reserved 5

bull 近年年のモバイルグラフィックスbull グラフィックスAPI のパラダイムシフトbull Low-‐‑‒Overhead Low-‐‑‒Level プログラミングbull Non-‐‑‒Photorealistic Rendering における水彩画表現bull まとめ質疑応答

セッションの内容

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 5: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 5

bull 近年年のモバイルグラフィックスbull グラフィックスAPI のパラダイムシフトbull Low-‐‑‒Overhead Low-‐‑‒Level プログラミングbull Non-‐‑‒Photorealistic Rendering における水彩画表現bull まとめ質疑応答

セッションの内容

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 6: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 6

近年年のモバイルグラフィックス

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 7: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 7

そもそもスマートフォンは多岐に渡る利利用用途がある

bull 電話メールメッセージアプリbull SNS (コミュニケーション)bull 動画視聴bull ゲーム

ゲームはあくまでコンテンツの一つユーザーはバッテリーリソースを消費しながらこれらコンテンツを利利用している

モバイルデバイスとゲーム

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 8: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 8

現在スマートフォン端末はフルHD(1920x1080px) の画面解像度度を持ったデバイスが一般的に普及している総ピクセル数で言えば約207万px ありこれを1秒間に60回書き換えを行行なっている

この膨大なピクセルの更更新を CPU を使用して行行うことも可能だがリアルタイム性を求めるゲームではレンダリング専用のプロセッサ(GPU)を通して画面更更新の高速化を図っている

rarr スマホゲーム通常は OpenGL ES を通して GPU で描画が行行われている

ゲームの更更新とレンダリング

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 9: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 9

OpenGL ES

OpenGL for Embedded SystemKhronos Group という標準化団体によって策定されている組み込み機器向けのグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 10: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 10

OpenGL ES は現在の iOS Android 開発を支える共通のグラフィックスAPI描画部分においては最も基本であり最も重要なAPIの一つ

現在のスマホネイティブアプリはiOSAndroid の両対応がほぼ一般的になっているがプラットフォームが異異なるこの2つのデバイスにおいてOpenGL ES でグラフィックスエンジンを記述すれば両プラットフォームの対応を行行うことができる

モバイルゲームを支えるAPI

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 11: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 11

グラフィックスAPI の呼び出しにより CPU で動作しているアプリケーションからGPU に対してタスクの発行行が行行われる(GPUドライバが制御する)

A社 の GPU と B社 の GPU でアーキテクチャが異異なってもこの共通の API によりその違いを吸収している

OpenGL ES

A_GPU_drawCall(Triangles 0 6)

DrawCall(Triangles 0 6 )

A社 GPU (SoC)

B_GPU_drawCall(Triangles 0 6)

B社 GPU (SoC)ハードウェア

ドライバ

アプリケーション

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 12: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 12

Khronos による仕様の策定

bull 2015年年8月には最新バージョンとなる ES 32 がリリースbull 現在のモバイルグラフィックスの多くは ES 20 をベースにしている

後述するMetal Vulkan もOpenGL ES と同じグラフィックスAPIの一つ

OpenGL ES

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 13: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 13

モバイルグラフィックスの推移

2003年OpenGL

ES 10

2004年OpenGL

ES 11

2007年OpenGL

ES 20

2012年OpenGL

ES 30

2014年OpenGL

ES 31

2015年OpenGL

ES 32

固定パイプライン時代第一世代グラフィックス

プログラマブルパイプライン時代第二世代グラフィックス

低レベルグラフィックスAPI時代第三世代(次世代)グラフィックス

2016年年MetalVulkan

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 14: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 14

グラフィックスAPIを選ぶ基準としてはOSサポートは勿論論端末に搭載されるGPU (ドライバ) の対応が必須となる

後述するMetal Vulkan も端末によってサポートが異異なるため留留意

グラフィックスAPI

OpenGL ES Android iOS20 22 iPhone3GS

30 43 iPhone5S

31+AEP 50 -

32 60 -

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 15: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 15

最新のモバイルグラフィックスは何が出来るかrarr ES 32 は DirectX110 世代と同等の機能を有しているbull 機能面だけで言えば PC PS4 XboxOne の世代に追いついているbull しかし性能面では大きな開きがあるため同等のグラフィックス表現は難しい

最新の OpenGL ES 32 ではコンピュートシェーダーは勿論論テッセレーションとジオメトリシェーダーまでサポートされている

モバイルグラフィクスの今

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 16: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 16

2012年年8月リリースES20 からは実に5年年ぶりのアップデート主な機能

レンダリングパイプラインの強化-‐‑‒ Occlusion Query-‐‑‒ Transform Feedback-‐‑‒ Instanced Rendering-‐‑‒ Multiple Render Targets

ETC2 テクスチャ圧縮形式のサポートand more

OpenGL ES 30

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 17: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 17

2014年年3月にリリースされた主な機能としてコンピュートシェーダ がサポートされた

-‐‑‒ Vertex Fragment オブジェクトの独立立-‐‑‒ Indirect draw Commands-‐‑‒ and more

ほぼ同時期に策定された Android Extension Pack というGL拡張も大きな注目を集めた

OpenGL ES 31

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 18: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 18

AEP とは 下記の GL 拡張のことを指しますGL_ANDROID_extension_pack_es31a

AEP はメタ拡張と呼ばれ開発者はこの GL 拡張が定義されている場合後述する20以上の拡張がサポートされていると見見なす

この拡張を GPU がサポートすることによりDirectX11 世代のゲームを Android への移植を容易易にした

Android Extension Pack (AEP)

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 19: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 19

KHR_debugKHR_texture_compression_astc_ldrKHR_blend_equation_advancedOES_sample_shadingOES_sample_variablesOES_shader_image_atomicOES_shader_multisample_interpolationOES_texture_stencil8 OES_texture_storage_multisample_2d_array EXT_copy_image

Android Extension Pack (AEP)EXT_draw_buffers_indexedEXT_geometry_shaderEXT_gpu_shader5 EXT_primitive_bounding_boxEXT_shader_io_blocksEXT_tessellation_shaderEXT_texture_border_clampEXT_texture_bufferEXT_texture_cube_map_arrayEXT_texture_sRGB_decode

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 20: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 20

OpenGL ES 最新の策定2015年年8月に仕様がリリース

-‐‑‒ Tessellation Geometry Shader-‐‑‒ ASTC テクスチャ圧縮-‐‑‒ Floating point render targets-‐‑‒ and more

OpenGL ES 32

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 21: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 21

bull モバイルグラフィックスAPI進化-‐‑‒ 現在主流流となっているのは ES20最新は ES32-‐‑‒ ES32 は DirectX110 世代と同等の機能を有している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 22: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 22

グラフィックスAPI のパラダイムシフト

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 23: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 23

従来のグラフィックスAPI と GPU の関係についてまずはアプリケーションから Draw 関数を呼び出すと何が起こるかを見見る

DrawCall とはグラフィックスAPI の描画処理理に関する関数呼び出しのことドライバは Draw 関数を一つの基準として処理理する

glDrawElements()D3D11DeviceContextDrawIndexed()

GPUの描画

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 24: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 24

1アプリケーションからグラフィックスAPI の呼び出しを行行うとドライバがメインメモリ上のコマンドバッファに内容を蓄積する

2DrawCall の呼び出しで コマンドバッファが一杯になるあるいは Flush Present が呼び出されるとドライバは GPU へのフラッシュを準備する

3ドライバが描画コマンドを GPU が解釈できる命令令に変換し同時に描画ステートのバリデーションを行行う

4GPU にコマンドが転送され処理理される

GPUの描画

ハードウェアにより実際の処理理は異異なるので留留意

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 25: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 25

基本的にドライバは Draw 関数を一つの基準として処理理し描画に関するステートをパッケージ化してコマンドバッファに積みGPU 転送時にバリデーションしていたこれらの処理理はドライバが暗黙のうちに行行う

GPUの描画

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

glClearColor(065f 065f 065f 10f)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)glBindVertexArrayOES(_vertexArray) glUseProgram(_program) glDrawArrays(GL_TRIANGLES 0 36)

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Draw CommandclearColor = 065f 065f hellipclearFlag = color | depth hellipvertexNum = 36 hellip

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 26: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 26

OpenGL ES では一部ベンダーの拡張を除いて標準機能としてはシェーダーのオフラインコンパイルをサポートしていない

シェーダーの字句句解析構文解析最適化命令令コードの生成の全てはドライバがランタイム上で実行行している

グラフィックスAPIのオーバーヘッド

void main()

vec3 eyeNormal = normalize(normalMatrix normal)vec3 lightPosition = vec3(00 00 10)vec4 diffuseColor = vec4(04 04 10 10)float nDotVP = max(00 dot(eyeNormal normalize(light))) colorVarying = diffuseColor nDotVP gl_Position = modelViewProjectionMatrix position

実行行時にGPU のマシンコードへ

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 27: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 27

余計なオーバーヘッドはCPU負荷を生みCPU負荷は発熱とバッテリー消費を招くこれがスマートフォン上では大きな問題となりえていた

静的に解決できるものは静的に解決し効率率率化できるものは効率率率化しランタイムでの CPU 負荷を削減することはできないか

低レベルグラフィックスAPIが生まれた

グラフィックスAPIのオーバーヘッド

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 28: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 28

2013年年以降降 グラフィックスAPI に大きな変革が起きている

AMD Mantle Apple Metal DirectX12 Khronos Vulkan など新しい API が登場した

コンシューマゲーム機では一般的であった低レベルAPI の思想が一般化

より効率率率的により明示的に CPUGPU を活用するrarr CPU のボトルネックを削減する

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 29: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 29

低レベルグラフィックスAPI

2013年年

2016年年2014年年

2015年年

AMD Mantle

Apple Metal

DirectX12

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 30: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 30

Metal Vulkan は最新のモバイルレンダリングアーキテクチャを最大限に活用する機能も含まれている例例えば一般的な下記3つの GPU に対応する

bull Immediate Mode Rendering (IMR)bull Tile Based Rendering (TBR) -‐‑‒ Mali Adrenobull Tile Based Deffered Rendering (TBDR) ndash PowerVR

詳細は後述

低レベルグラフィックスAPI

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 31: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 31

Apple が策定 2014年年9月にリリース(iOS8〜~OSX El Capitan〜~)iOS の対応が先行行して行行われ翌年年に mac OSX のサポートも行行われた

2016年年6月の WWDC2016 でもMetal のアップデートが発表された大きな更更新としてはiOS で初めて テッセレーション() がサポートされる

Apple Metal

mac OSX sierra iOS10 の iPhone6s iPhone6s Plus iPhone SE 以降降のデバイスが必須A9プロセッサー(PowerVR 7XT) でないとハードウェアがテッセレータを搭載していないため

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 32: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 32

2016年年2月に Vulkan 10 がリリースモバイルからデスクトップまで幅広いプラットフォームをサポートしている

当初glNext と呼ばれていたLunarG 社より WindowsLinux の Vulkan SDK が提供されているGoogle からも Vulkan ビルドに対応したNDK がリリースされています

Khronos Vulkan

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 33: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 33

描画時はフレームバッファ(Color Depth Stencil)へのアクセスに注意フレームバッファのサイズが大きい場合 Depth Stencil Buffer などシステムメモリアクセスに伴うフレームバッファの転送の負荷が大きい

この負荷を下げるために最新のモバイル GPU の特徴としてTile Based Rendering アーキテクチャを採用している

Modern mobile architecture

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 34: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 34

Tile Based Rendering

GeometryProcessing Tiling Rasterize Visibility

TestFragmentProcessing

Alpha TestAlpha Blend

On-shyChipDepth Buffer

On-shyChipColor Buffer

Primitive ListVertex Data Texture Data Frame BufferGeometry

Data

On-‐‑‒Chip Memory

System Memory

レンダリング時は可能な限りシステムメモリへのアクセスを避ける高速な On-‐‑‒Chip 上のメモリに置かれたタイルバッファへの読み書きを行行う

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 35: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 35

Metal Vulkan はこの TBR アーキテクチャに最適化されている描画時に高速な On-‐‑‒Chip 上のバッファだけでレンダリングを完結させることが出来る

そのため負荷の高いシステムメモリへのアクセスを避けることが可能でこれにより消費電力力が削減できる

Tile Based Rendering

On-shyChipDepth Buffer

On-shyChipColor BufferOn-‐‑‒Chip Memory

Frame BufferSystem Memory

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 36: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 36

レンダリング時におけるフレームバッファのアクセスは

MetalMTLRenderPassDescriptorVulkanVkAttachmentDescription 構造体に指定する

それぞれ loadAction(op) storeAction(op) というメンバ変数を持っておりレンダリングパス開始時終了了時のフレームバッファの取り扱いを設定する

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 37: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 37

loadAction(op)-‐‑‒ Clear hellip フレームバッファの内容を指定の色でクリア-‐‑‒ Load hellip フレームバッファの内容を読み込む (On-‐‑‒chip へのコピー発生)-‐‑‒ DontCare hellip 全てのピクセルが更更新される際に指定

storeAction(op)-‐‑‒ Store hellip フレームバッファへ書き出す-‐‑‒ DontCare hellip DepthStensil などフレームバッファへ書き出す必要がない場合

(プラットフォームごとに最適なパフォーマンス結果となる)

Tile Based Rendering

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 38: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 38

低レベルグラフィックスの思想として静的に決定できる物は静的に解決するrarr ラインタイム時にかかる CPU パワーを排除

bull パイプラインステートbull シェーダーコンパイルbull 描画のバリデーション

静的に解決する

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 39: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 39

Pipeline State Object とは描画に関する情報のことOpenGL ES 世代では個々に指定されていたが一まとまりで定義されるようになったステートは生成時に検証されるため実行行時のオーバーヘッドがない

GPU はこの Pipeline State オブジェクトを差し替えるだけで次のレンダリングに移ることができる

MetalMTLRenderPipelineStateVulkanVkPipeline オブジェクトに保持される

パイプラインステート

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 40: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 40

Metal Vulkan ともにシェーダーのオフラインコンパイルをサポート-‐‑‒ シェーダーはオフラインでコンパイルする-‐‑‒ ランタイム時の生成コストを排除

シェーダーコンパイル

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 41: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 41

OpenGL API 呼び出しのエラーチェックはドライバで実装されておりbull 最後に発生したエラーを glGetError() bull Debug Release 問わず エラーチェック

Metal Vulkan 世代では明示的に Validation Layer を有効にすることでAPI 呼び出しのエラーチェックを実施する

通常は開発時に有効にして製品版では無効にし CPU のオーバーヘッドを削減する

バリデーション

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 42: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 42

bull 従来の グラフィックスAPI ではコマンドバッファ構築はドライバの仕事だったbull Metal Vulkan 世代ではアプリケーションマターへと変わったbull CommandBuffer に対してコマンドを追加bull CommandBuffer を CommandQueue にサブミットする

コマンドバッファ構築

Buffer Texture RenderPass Draw

CommandBuffer

CommandQueue

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 43: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 43

CommandBuffer はマルチスレッドで構築できる空いた時間で更更に多くの Draw を発行行するかまたはCPUを休めれる

コマンドバッファ構築

Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CommandBuffer Thread0

Thread1

Thread2

Thread3

0ms 5ms 10ms 15ms

CB

CB

CB

CB

Single-‐‑‒Thread Multiple-‐‑‒Thread

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 44: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 44

Metal と Vulkan において Queue と Buffer では使い方が異異なるので注意

Metal は基本的に一つの Queue 上に Command Buffer を追加していくVulkan は graphics と compute で Queue が分かれて個別にサブミットする(VKSemaphore で Queue の同期を取る)

コマンドバッファ構築

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 45: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 45

ブロック圧縮アルゴリズムの一種iOS であれば PVRTC Android であれば ETC が一般的に使われてきた

Metal Vulkan 世代では ASTC という統一的な圧縮フォーマットが使用できるrarr 今までのようにプラットフォームごとに圧縮を分ける必要はない

Adaptive Scalable Texture Compression (ASTC)

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 46: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 46

Low-‐‑‒Overhead Low-‐‑‒Level プログラミング

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 47: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 47

iOS macOS の Apple プラットフォームのみサポート開発環境も macOS 上の Xcode が必須となる

開発環境OSX El Capitan Xcode7 以降降実行行環境iOS 8 iPhoen5s (Apple A7) 以降降

2012年年以降降に発売された MacBook iMac など

Metal の環境

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 48: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 48

最新の macOS と Xcode と iOS デバイスがあれば開発出来るXcode の新規プロジェクト作成より Game -‐‑‒gt Metal を選べばテンプレートプロジェクトが作成される

Metal の開発環境

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 49: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 49

Metal の開発環境

httpsdeveloperapplecommetal

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 50: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 50

Validation Layer

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 51: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 51

bull MTLDevicebull MTLCommandQueuebull MTLLibrarybull MTLFunction(Shader) bull MTLBufferbull MTLRenderPipelineStatebull MTLDepthStencilStatebull MTLRenderPassDescriptor

bull MTLRenderPassColorAttachmentDescriptorbull MTLRenderPassDepthAttachmentDescriptor

bull MTLCommandBufferbull MTLRenderCommandEncoder

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 52: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 52

以降降のスライドで実際の Metal のコードを記述していますが説明のため重要コードのみピックアップして記載している点に注意して下さい

完全なソースは Apple Developer のサンプルを参考にして下さい

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 53: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 53

ベースとなる初期化部分デバイスの取得コマンドキューライブラリは下記のコードで取得ライブラリはシェーダーのアーカイブ

Metal Programming

idltMTLDevicegt device = MTLCreateSystemDefaultDevice()

idltMTLCommandQueuegt commandQueue = [device newCommandQueue]idltMTLLibrarygt defaultLibrary = [device newDefaultLibrary]

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 54: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 54

シェーダー作成

Metal Programming

[defaultLibrary newFunctionWithNamelighting_fragment][defaultLibrary newFunctionWithNamelighting_vertex]

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 55: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 55

Metal Programming

MTLRenderPipelineDescriptor pipelineDescriptor = [MTLRenderPipelineDescriptor new]pipelineDescriptorvertexDescriptor = vertexDescriptor 頂点レイアウトpipelineDescriptorvertexFunction = vertexFunction VertexシェーダーpipelineDescriptorfragmentFunction = fragmentFunction FragmentシェーダーpipelineDescriptorcolorAttachments[0]pixelFormat = MTLPixelFormatBGRA8UnormpipelineDescriptordepthAttachmentPixelFormat = MTLPixelFormatDepth32Float

パイプラインステートを設定

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 56: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 56

Metal Programming

idltMTLRenderPassDescriptorgt _renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]

MTLRenderPassColorAttachmentDescriptor colorAttachment = _renderPassDescriptorcolorAttachments[0]colorAttachmentloadAction = MTLLoadActionClearcolorAttachmentstoreAction = MTLStoreActionStorecolorAttachmentclearColor = MTLClearColorMake(065f 065f 065f 10f)

MTLRenderPassDepthAttachmentDescriptor depthAttachment = _renderPassDescriptordepthAttachmentdepthAttachmentloadAction = MTLLoadActionCleardepthAttachmentstoreAction = MTLStoreActionDontCaredepthAttachmentclearDepth = 10

パイプラインパスを設定

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 57: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 57

コマンドバッファの構築Metal は CommandEncoder という仕組みでコマンドバッファに追加

Metal Programming

id ltMTLCommandBuffergt commandBuffer = [_commandQueue commandBuffer]id ltMTLRenderCommandEncodergt renderEncoder =

[commandBuffer renderCommandEncoderWithDescriptordesc]

[renderEncoder setDepthStencilState_depthState][renderEncoder setRenderPipelineState_pipelineState][renderEncoder setVertexBuffer_vertexBuffer offset0 atIndex0 ][renderEncoder drawPrimitivesMTLPrimitiveTypeTriangle vertexStart0 vertexCount36][renderEncoder endEncoding]

[commandBuffer presentDrawableviewcurrentDrawable][commandBuffer commit]

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 58: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 58

Metal Programming

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 59: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 59

Vulkan はクロスプラットフォームに対応する2016年年8月現在Windows Linux Android Tizen と言った各種プラットフォームをサポートしている

Windows Linux の SDK が LunarG 社より提供されている

Vulkan の環境

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 60: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 60

Android 70 (Nougat) 以降降でサポートbull 2016年年3月より開発者向け Preview と NDK がリリースbull 2016年年8月23日に正式版リリースbull 現時点の対応端末は Nexus 6 Nexus 5X Nexsus 6P Nexsus 9

bull Android Studio にインポートできるサンプルが提供されているVulkan-‐‑‒basic-‐‑‒sampleshttpsgithubcomgooglesamplesvulkan-‐‑‒basic-‐‑‒samples

Vulkan の実行行環境

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 61: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 61

Vulkan は SPIR-‐‑‒V と呼ばれる中間バイナリーデータをサポートしているrarr Graphics Shader Compute Kernel などは SPIR-‐‑‒V でロードする

GLSLHLSL でシェーダーを記述しビルド時に SPIR-‐‑‒V を生成する

SPIR-‐‑‒V

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 62: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 62

Vulkan は vkInstance を生成することから始めるプラットフォームごとの描画サーフェスや実行行に必要なレイヤーなどシステムへのアクセスは vkInstance を通して行行われる

Vulkan Programming

VkInstance instvkCreateInstance(ampinst_info NULL ampinst)

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 63: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 63

vkInstance からシステムの物理理デバイスを取得する物理理デバイスからアプリで使う GPU インターフェース VKDevice が作成できる

Vulkan Programming

VkPhysicalDevice physical_devicesVkDevice devicevkEnumeratePhysicalDevices(inst ampgpu_count ampphysical_devices)vkCreateDevice(physical_devices ampdeviceInfo NULL ampdevice)

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 64: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 64

vkCreateRenderPassvkCreateShaderModulevkCreateGraphicsPipelinesvkAllocateDescriptorSetsvkUpdateDescriptorSetsvkCreateCommandPoolvkAllocateCommandBuffersvkCreateImagevkCreateImageView

Vulkan Programming

vkCreateBuffervkBindBufferMemoryvkCreateDescriptorSetLayoutvkCreatePipelineLayoutvkCreateDescriptorPoolvkCreateFramebuffervkAllocateMemoryvkBindImageMemory

VKDevice を通して下記オブジェクトリソースを生成する長くなるので Draw の解説のみに割愛

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 65: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 65

Vulkan のコマンドバッファは VkCommandBufferこれは vkAllocateCommandBuffers を通してコマンドプールより確保される

vkBeginCommandBuffer vkEndCommandBuffer でコマンドを構築し構築したコマンドを vkQueueSubmit でキューに追加する

コマンドキューは Graphics Compute Transfer 用途ごとに分ける必要がある

Vulkan Programming

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 66: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 66

vkBeginCommandBuffervkCmdPipelineBarriervkCmdBeginRenderPassvkCmdBindPipelinevkCmdBindDescriptorSetsvkCmdSetViewportvkCmdBindVertexBuffersvkCmdDrawvkCmdEndRenderPass

vkEndCommandBuffer

Vulkan Programming

一度度作成したVulkan のコマンドバッファは次フレームでも再利利用が可能

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 67: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 67

Metal Vulkna はアプローチが似ており共通項目が多いbull 片方を理理解すればもう片方を覚えるのもそこまで大変ではないbull 言語を覚えるというよりも低レベルAPIの思想を知った方が理理解が早い

Metal Vulkan まとめ

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 68: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 68

Non-‐‑‒Photorealistic Rendering における水彩画表現

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 69: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 69

Non-‐‑‒Photorealistic Rendering (NPR) はコンシューマゲームに代表されるフォトリアルな絵作りとは対を成すレンダリング技法

トゥーンシェーダなどのアニメ調の表現も NPR の技法に区分される

Non-‐‑‒Photorealistic Rendering

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 70: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 70

フォトリアルな絵作りに必要な要素を考えてみるbull HDRレンダリングbull 高解像度度テクスチャハイレゾメッシュbull Physically Based Renderingbull Global Illuminationbull 高品質なアンチエイリアスbull カラーグレーディングbull Depth of Fieldsbull 多数の動的ライト

なぜNPRなのか

これらの処理理をモバイルで実現

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 71: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 71

モバイルが抱える問題にはバッテリー消費発熱の問題がある演算一回メモリアクセス一回にも僅かながらバッテリーを消費しており時間とともに某大なバッテリー消費へと発展する

CPUGPUに余裕があっても追加のグラフィックス用途を組み込むということがやり辛い環境にある

モバイルのジレンマ

現実的なバッテリー消費と絵作りの品質についてそのトレードオフを考える

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 72: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 72

現実的なタスク量量で実現可能な絵作りとはコンシューマはハードウェアと技術の進歩により現実的なタスク量量でのフォトリアルレンダリングを実現する手段を得た

モバイルもフォトリアルな絵作りのためにハードウェアの進化を待つかrarr GPU の性能向上は画面の高解像度度化に相殺される可能性もある

それよりプラットフォームが異異なり提供できるゲームの形が異異なるのだから絵作りの方向性もまたコンシューマのリアルとは別路路線に振り切切ってみる

NPRへのモチベーション

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 73: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 73

水彩画を表現

本物の水彩画です

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 74: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 74

bull 多彩なアプローチrarr PBR 実装のような物理理現象への依存が少ないため実装が容易易rarr 視覚的効果が高い実装の追求が可能

bull オブジェクト描画時に統一的なマテリアルになることが期待できるrarr バッチ描画できる可能性が増えるrarr 質感はポストプロセスで掛ける基本は1マテリアルで描画できる

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 75: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 75

bull 質感をポストポロセスへrarr 描画マテリアルの簡素化rarr 描画オブジェクト数に依存せずにNPR に関する負荷を固定で見見積もる

bull 繊細な表現ではなく視認性の高さを評価し採用rarr 例例えば日本アニメとの親和性の高さなど

アニメ表現はほぼ一般的に行行われているため今回は同じ題材を選ぶよりは思考を変えて水彩画に挑戦する

NPRの利利点

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 76: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 76

bull 水彩画に使われる水彩紙の表現紙肌の粗目による凹凸感

bull 絵の具のにじみぼかしかすれ表現輪輪郭部分は他の色と混ざり合いグラデーションがかかる

bull デジタル特有のポスト加工処理理の追加水彩表現をベースとした上で更更にゲームの世界観の向上へ

水彩画の特徴

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 77: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 77

水彩紙とは透明水彩や不不透明水彩などの水彩絵具を用いた描画に適した専用紙の総称

紙質によっては高い吸水性を保持しており水分量量を調整することでにじみやぼかし効果に大きな影響を与えることができる

水彩紙の表現

httpzokeifilemusabiacjpE6B0B4E5BDA9E7B499

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 78: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 78

水彩は絵の具に含まれる水分と水彩紙特有の吸収性によりにじみやぼかしが効果が起こる

塗り方によりエッジ部分は他の色と薄く混ざり合う

絵の具のにじみぼかし

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 79: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 79

水彩表現のアプローチ

Final result

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 80: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 80

Final result

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 81: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 81

水彩表現のアプローチ

Texture only

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 82: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 82

水彩画表現のアプローチ

Final resultTexture only

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 83: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 83

bull Multiple Render Target で G-‐‑‒Buffer にシェーディング情報の書き出しbull G-‐‑‒Buffer は2枚使用bull DiffuseMap と ハッチングを含むアウトライン線bull 絵の具のにじみ方向を書き込んだ VectorMap

bull Compute Kernel で水彩表現を処理理bull コンポジット

水彩画表現のアプローチ

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 84: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 84

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer1

DiffuseMap Hatching + Outline

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 85: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 85

G-‐‑‒Buffer への書き出しG-‐‑‒Buffer2

VectorMap

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 86: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 86

モデルに適用する VectorMap は FlowMapPainter を使用して作成

G-‐‑‒Buffer への書き出し

httpteckartistcompage_id=107

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 87: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 87

FlowMap の XY には流流れの方向が記述されているこの 流流れ を水彩のストロークとして使用このベクトルの移動量量をにじみの方向に

G-‐‑‒Buffer への書き出し

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 88: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 88

G-‐‑‒Buffer への書き出しfloat3 diffuseColor = diffuseTexturesample(samplr verttexCoord)rgbfloat3 normal = normalize(vertnormal)float3 eyeDirection = normalize(verteyePosition) NdotEhalf NdotE = dot( normal eyeDirection ) hatchinghalf hatching = hatchingTexturesample(samplr verttexCoord)xhatching = mix(hatching half(10f) half(015f )) Outlinehalf4 edgeColor = half4( half3( 06f ) 10f )half edgePower = 50fhalf4 outline = saturate( half4( NdotE edgePower hatching ) + edgeColor ) Flowmapfloat4 flowmap = flowmapTexturesample(samplr verttexCoord)flowmapxy = (flowmapxy float2(05f) ) + float2(05f)

MXFragOutput outputoutputalbedo = float4( diffuseColor outlinex )outputnormal = float4( flowmapxyz 10f )return output

Fragment shader

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 89: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 89

G-‐‑‒Buffer で書き出した2枚のテクスチャを Compute Kernel へ入力力する書き出した VectorMap の情報をもとに DiffuseMap のテクスチャ位置をずらしてサンプリングする

Compute Kernel

half4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower )

gidy + (int)( inColor2y flowPower ))

half4 flow = inTextureread( coord )

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 90: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 90

Compute Kernel

VectorMap 適用した結果

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 91: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 91

思ってた結果にならないhellipもっとぐにゃっと曲がってほしい

殆どのモデルの VectorMap サンプリング位置が均一になっているrarr VectorMap の方向ベクトルとモデルの UV 位置が問題

Compute Kernel

ただモデルごとに個別に VectorMap を用意するのもUV を修正するのもやりたくない

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 92: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 92

回避策bull VectorMap にノイズで重み付けを行行うbull サンプリングした VectorMap に揺らぎをつける

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 93: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 93

ランタイム上の Compute Kernel で Perlin Noise を生成するrarr 起動時に生成して G-‐‑‒Buffer と一緒に Kernel へ入力力する

Compute Kernel

half rand( half2 n ) return fract( sin( dot( n half2(129898f 41414f ) ) ) 437585453f )

half perlinNoise( half2 p )half2 ip = floor(p)half2 u = fract(p)u = u u (30f - 20f u )half res = mix( mix( rand( ip )

rand( ip + half2( 10f 00f ) ) ux )mix( rand( ip + half2( 00f 10f ) )

rand( ip + half2( 10f 10f ) ) ux ) uy)return res res

httpsgistgithubcompatriciogonzalezvivo670c22f3966e662d2f83

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 94: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 94

Compute Kernel

VectorMap only VectorMap + Perlin Noise

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 95: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 95

元の DiffuseColor とずらした DiffuseColor を合成する合成時は Perlin Noise の重み付けをもとに色を mix する

Compute Kernel

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 96: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 96

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 97: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 97

Compute Kernel

Diffuse only ブレンド結果

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 98: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 98

Compute Kernelhalf4 inColor = inTextureread(gid)half4 inColor2 = inTexture2read(gid)

half flowPower = 800fuint2 coord = uint2( gidx + (int)( inColor2x flowPower noise )

gidy + (int)( inColor2y flowPower noise ))

half4 flow = inTextureread( coord )

輝度が高すぎるので輝度を落とすflow = mix( flow half4( 10f ) (half)03f )inColor = mix( inColor half4( 10f ) (half)01f )

パーリンノイズの強度をブレンドの強度にするhalf flowBlend = noisehalf4 originMix = mix( inColor flow flowBlend )

ハッチングとアウトラインを書き出すoriginMixw = inColorwoutTexturewrite( half4( originMix ) gid )

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 99: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 99

Hatching + Outline の線は次のぼかしパスがあるためComputeKernel からはテクスチャの w 要素に入れて書き出しておく後のコンポジットパスで合成する

Compute Kernel

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 100: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 100

結果をさらに Compute Kernel で加工するbull 12 にダウンサンプリングbull ガウスぼかし

Compute Kernel

このぼかした結果を最終的なコンポジットパスで合成する

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 101: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 101

コンポジットの段階では3枚のテクスチャを利利用するbull にじみテクスチャbull ぼかしテクスチャbull 水彩紙テクスチャ

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 102: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 102

水彩紙テクスチャ

事前に Photoshop のフィルターで作成水彩紙の凹凸を表現したテクスチャコンポジットで合成する

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 103: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 103

にじみテクスチャとぼかしテクスチャをブレンドする

コンポジット

half blendRate = 051freturn mix( color0 color1 blendRate )

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 104: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 104

コンポジット

ソフトフォーカスのような効果が得られる

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 105: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 105

コンポジット

この時ブレンドする BlendRate が高すぎるとぼやけた絵になるので注意

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 106: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 106

ブレンド前

コンポジット

ブレンド後

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 107: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 107

この結果に対してスクリーン全体に水彩紙テクスチャを追加する

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) paperTex

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 108: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 108

コンポジット

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 109: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 109

更更にハッチングとアウトライン線を追加

コンポジット

float2 screenUV = (inFragpositionxy uniformsscreenSize)half4 paperTex = paperTex2Dsample(quadSampler screenUV)

half4 color0 = tex2Dsample(quadSampler inFragtexCoord)Half4 color1 = blurTex2Dsample(quadSampler inFragtexCoord)

half blendRate = 051freturn mix( color0 color1 blendRate ) color0w paperTex

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 110: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 110

コンポジット

Final result

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 111: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 111

Final result

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 112: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 112

bull モバイルでも NPR は現実的な負荷で処理理できるbull アイディア次第で全く新しいグラフィックス表現が実現できる可能性

bull ベースとなる GPU の機能強化と性能向上bull Metal Vulkan に対応する GPU そのもののベース性能が向上しているbull 各 GPU 機能の均一化が進み拡張に依存しない統一的な実装環境

bull Shader が書きやすいbull GLSLでは include define が使えないため複雑なシェーダーが書き辛いbull MSL SPIR-‐‑‒V(変換前のシェーダー) ではコンパイル時にプリプロセッサが働く

まとめ

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 113: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 113

bull モバイルでは処理理負荷の1msecを削減することに意味があるbull 低レベルグラフィックスAPIはモバイルにこそ価値があるbull バッテリー消費と発熱の問題を考える上で僅かなオーバーヘッドの削減はアプリ全体の継続率率率にも影響を与える

bull 今後の低レベルグラフィックスAPIbull 登場時期の速さから今は Metal が先行行して普及しているbull Vulkan も対応プラットフォーム数の多さからいずれ Metal に追いつくbull 2018年年頃には モバイルでの低レベルグラフィックスAPI が一般化している

まとめ

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました

Page 114: CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介

Copyright Drecom Co Ltd All Rights Reserved 114

ご清聴ありがとうございました