フォグ
フォグ(英語:fog)とは、3DCGにおいて、カメラから一定以上の距離の描画を霧がかったようにすることをいう。
概要
プリレンダリングでは主に遠近感を出したい場合に薄いフォグを掛けるという手法が用いられる。
ゲームなどのリアルタイムレンダリングでは遠方にあるモデルを真面目に描画すると無駄に重くなるので、濃いフォグを掛けて「これ以上は見えません(描画しません)」としてしまう手法として用いられることが多い。
実装
PCが低速だった時代の古いDirect3DやOpenGLなどでは「強烈なフォグを掛けてあたりまえ」であったため標準機能として備わっていた。
プログラマブルシェーダー全盛時代に入るとフォグまで自前で実装する風潮になり、最近のDirectX 12やMetal、VulKan、WebGLでは標準でフォグを書ける機能はバッサリ削除されている。これらでフォグを使いたければ自前でシェーダーを実装する必要がある。
Direct3D (シェーダー未使用)
古いDirectXでシェーダーを使わない、シェーダーがない世代では以下のような実装であった。 デバイス(≒GPU、稀にCPUでGPUをエミュ)にパラメーターを渡す感じだね。
DWORD Color;
DWORD Mode;
float Start = 0.5f;
float End = 0.8f;
float Density = 0.66f;
// フォグを有効にする
m_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
// フォグカラーを設定する
m_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
// その他のパラメーターを設定する
if (Mode == D3DFOG_LINEAR)
{
m_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
m_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
m_pDevice->SetRenderState(D3DRS_FOGEND, *(DWORD *)(&End));
}
else
{
m_pDevice->SetRenderState(D3DRS_FOGTABLEMODE, Mode);
m_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
}
MonoGame
MonoGameではBasicEffectクラスにFogEnabledなどのプロパティが用意されており、BasicEffectを使う限りは簡単に利用できる。こちらは内部的にはシェーダーでの実装となっている。
basicEffect.FogEnabled = true;
basicEffect.FogColor = Color.White.ToVector3();
basicEffect.FogStart = 9.75f;
basicEffect.FogEnd = 10.25f;
当然ながらBasicEffectではなく自前のシェーダーを使う場合は自前実装になる。自前実装する場合はググって一般的なフォグの実装を移植するのが簡単だと思われる。githubからBasicEffectのソースコードを落としてきて眺めてみたが、他の処理の絡みもあって「ソース読め」とは言えないレベルで複雑なことになっている。
Metal
そのうち書く。
Vulkan
そのうち書く。
WebGL
知らんがな。