Numpy での ベクトル処理

import numpy as np

a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])

a = a / np.linalg.norm(a)
b = b / np.linalg.norm(b)

np.dot(a, b)
np.cross(a, b)

面法線の求め方

import numpy as np

v0 = np.array([0.0, 0.0, 0.0])
v1 = np.array([0.0, 0.0, 0.0])
v2 = np.array([0.0, 0.0, 0.0])

t0 = v1 - v0
t1 = v2 - v0

n = np.cross(t0, t1)
print(n)

外積はかける順番で結果が異なる(法線の方向が逆を向く)ので注意。

下記記事を参考にさせて頂きました。素晴らしい記事をありがとうございます。
https://deepage.net/features/numpy-dot.html

DirectML 覚書

Trained Weights Source
https://github.com/microsoft/DirectML-Samples/issues/3
DirectML では生の重みデータしか使えず、ONNX などを使いたい場合は 上位の Windows Machine Learning を使用する。

Direct Machine Learning (DirectML)
https://docs.microsoft.com/en-us/windows/win32/direct3d12/dml

Accelerating GPU inferencing with DirectML and DirectX 12
https://www.highperformancegraphics.org/wp-content/uploads/2018/Hot3D/HPG2018_DirectML.pdf

Using AI for Interactive Applications
http://on-demand.gputechconf.com/gtc/2018/presentation/s8957-using-ai-for-interactive-applications.pdf

USING AI TO ACCELERATE YOUR GAME (PART 2)
https://devblogs.microsoft.com/directx/wp-content/uploads/sites/42/2018/03/WinML_acceleration_GDC.pdf

NVIDIA TURING GPU ARCHITECTURE
https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/technologies/turing-architecture/NVIDIA-Turing-Architecture-Whitepaper.pdf

Windows 10 1903 であれば、Windows Machine Learning を使ったときは、対応している GPU さえあれば内部で DirectML が動いているのだろうか。

DirectML は Inferencing (推論) のための API なのでネットワークを学習する機能が提供されていない。自前で組み込むか、もしくは何かしらの別のフレームワークを使って学習させた結果をコンバートしなければいけない。

GPU の非同期実行

DirectX12 や Vulkan の長所はここ。

DirectX12で非同期コンピュート もんしょさん
https://sites.google.com/site/monshonosuana/directxno-hanashi-1/directx-147?tmpl=%2Fsystem%2Fapp%2Ftemplates%2Fprint%2F&showPrintDialog=1

AMDが Async Shaders を猛烈にアピール。とっくに実装済みの機能が DX12時代の切り札となる!?
https://www.4gamer.net/games/033/G003329/20150330067/

Asynchronous Shaders White Paper
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Asynchronous-Shaders-White-Paper-FINAL.pdf

Participating Media の Rendering

視点から LTE の両辺を積分したものをボリュームレンダリング方程式と呼び、これが Participating Media のレンダリング結果になる。視点から媒質に向けたレイでいい。ボリュームレンダリング方程式を細かい区間で区切って、奥から計算して次の領域に減衰させて引き渡す。これを再帰的に繰り返して求め、値を全て足し合わせたものが、積分の結果に近似できる。

参考文献:CG Magic
素晴らしい本に感謝

Subsurface Scattering Model

Vray

VRayFastSSS2
https://docs.chaosgroup.com/display/VRAY4MAYA/VRayFastSSS2
Vray の SSS 実装のパラメータ

Scale
値を大きくすると、透明度が増す。耳たぶとか、主に視点からの厚みが薄い所がが透過されやすくなり、明るくなっていく。

Sub-Surface Color
マテリアルの外観の色に影響する。いわゆる Base Color 部分。

Scatter Color
Scale 値によって透過した際に出てくる色。例えば、青とかを設定すると耳たぶの薄い部分とかが、青っぽくなる。Scale 値を大きくすると、Scatter Color の割合が高くなる。

Phase Function
このパラメータは、サーフェース上の Diffuse と Glossy reflection の違いに似ている。この値はボリュームの、Reflectance (反射率) と Transmittance (透過率) に影響する。

Arnold

Subsurface
https://docs.arnoldrenderer.com/display/A5AFMUGJPN/Subsurface?desktop=true&macroName=center

Radius (影響範囲)
Mean Free Path (MFP:平均自由行程) を意味していて、ライトがサーフェース下をどれだけ移動できるかを指定できる。値が大きいと、ライトの移動距離が長くなり滑らかに見えるが、値が小さいと、不透明に近づく。RGB の個別にどれくらい移動するかを指定できる。RGB (1.0, 0.35, 0.2) のような値を設定すれば、R 成分が最も多く移動する。

Weight
Diffuse と Subsurface のブレンド値を設定できる。1.0 だと SSS のみ。通常は 1.0 しか使わない。

CG の反射モデル メモ

BSSRDF

今のゲームグラフィックが、ゲームグラフィックっぽく感じるのは様々な要因があるが、その中の一つに Microfacet BRDF の存在がありそう。金属以外の全ての物体は僅かながら内部散乱を起こすが、今は無視している。軽量な Microfacet BSSRDF に発展させないと、品質は上がらない。でも、普通のラステライザではたぶんムリ。

SSS

V-Ray などの SSS マテリアルには diffuse color が設定できるが、通常は使わない? 肌の上では Specular か、Sub-Surface color (Scatter color) が見えてくる。顔の上にシールを貼っていたり、ペイントとかしてたら diffuse color っぽい。

IOR

屈折率のことを IOR (Index of Refraction) と呼ぶ。レンダラーによっては、IOR の値を設定して反射を制御する。IOR のパラメータは自動的に Fresnel に変換されて(連動して)、反射として使われる。

水は ior 1.333。下記の式に入れると、0.02 という値が出る。
f0 = ((ior-1)^2)/((ior+1)^2)
これは F0 だと 2%の反射率ということになる。

真空中の光速度 c を媒質中の速度 v で割った値で定義される。n = c / v。水の中などでは光の進む速度は遅くなるため屈折する。 真空中の光の速度を超える速度は出すことはできないため、IOR の値は 1 を下回らない。代表的な数値は、空気:1.0003 。ガラス:1.5。ダイアモンド:2.419など。値が大きい媒質中ほど、光の進み具合は遅くなっている。

IOR の値が分かれば、Snell’s law を使って、屈折の角度も計算することが出来る。コンピュータグラフィイクスで屈折表現する時は、Shell’s law から屈折方向を導く。

IOR の値が分かれば、F0 反射率も計算できる。
f0 = ((ior-1)^2)/((ior+1)^2)

逆に F0 の値を知っていれば、この式で IOR が分かる。
ior = 2/(1-sqrt(f0))-1

Microfacet BRDF

F * G * D
Fresnel * Geometry Function * Normal Distribution Function
(F * G * N ではないのは、N 法線と勘違いされるためだろう)

Fresnel

媒質が異なる(空気->金属, 空気->絶縁体, 空気->水) などに光がぶつかった時に、光の方向と表面の法線に依存して、一部は反射し一部は屈折する。このふるまいが Fresnel。という説明を良く見かけるが、分かったようでいて分かっていなかった Fresnel。

つまり、入射した光の何%が反射するかを考えるもの。屈折は物体内部に入り込む光だが、ラスタライザだと表現することは厳しいので通常モデルだと無視して反射だけを考える。法線に光が垂直に入射した場合 F0 として定義され、F90では反射率1(100%)になる。媒質によもよるが、光と法線の角度が0度から45度では F0 の値に近く、75度を超えたあたりから、急速に反射率1に近づく。そのためエッジ部分がが明るく感じられる。

Gold だと F0 の値は RGB (255, 229, 158) で入力される。ただ、画面上で見たときは “金っぽい色” で表示されるが、画面で見たときの色という視点では見ずに、これは F0 時点で既に R:255, G:229, B:158 の反射率を持っているということを示している。(R:255なので F0 時点で既にRは100%反射するということ)

Normal Distribution Function (NDF)

日本語だと正規分布関数。あるサーフェス点における、ある方向を向く Microfacet がどれくらい集中しているか。NDF はハイライトのサイズと形状を決定する。

Geometry Term

Geometry または、shadowing-masking function と呼ばれる。光と視線の方向から、照らされて見える(影やマスクになっていない)部分を決める。Light と View と Half Vector を変数とする関数。

Google Filament のシェーディング

main.fx の main() がエントリーポイント
shading_lit.fs の evaluateMaterial() が呼ばれ、その中の evaluateLights() がライティング用の関数。shading_lit.fs の中に evaluateLights() があり、evaluateIBL() -> evaluateDirectionalLight() -> evaluatePunctualLights() の順番で呼ばれている。

evaluateIBL, evaluateDirectionalLight, evaluatePunctualLights のそれぞれで、surfaceShading() が呼ばれている。standard, cloth, subsurface が surfaceShading() を実装している。マテリアルによって切り替えている。

Numpy 覚書

import numpy as np

# 10個の連続する値を確保
a = np.arange(10)
=> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

# 2次元配列の確保
a = np.arange(10).reshape(2, 5)
=> [[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]

# 多次元配列
a = np.arange(40).reshape(5, 2, 2, 2)
[ [[[0,1], [2,3]], [[4,5],[6,7]]], [[[8,9],[10,11]],…..

a[0][0][0][0] => 0
a[0][0][0][1] => 1
a[0][0][1][0] => 2
a[0][1][0][0] => 4
a[1][0][0][0] => 8