🌍

(Somewhat more) Physically based rendering 物理的に(もう少し)正しいレンダリング

2023/12/24に公開

テスト。Notionからのコピー。
Test. Copied from Notion.

Let’s learn about the nature of light by learning more physically accurate rendering techniques. Here we will use LearnOpenGL.com's implementation as a reference so that we can run it in real time in the browser. The details of the implementation in the linked page, so the emphasis here is on learning the basic concepts.

より物理的に正確なレンダリング手法を学ぶことで、光の性質について学びましょう。ここではブラウザ上でリアルタイムに動かせるように LearnOpenGL.com の実装を参考にします。実装の詳細はリンク先で細かく説明されているので、ここでは基本的な考え方を説明することに重きを起きます。

https://learnopengl.com/PBR/Theory

Filament's page is also a very helpful resource.

Filament のページも参考になります。

https://google.github.io/filament/Filament.html

Environment Light 環境光

On the page about classic methods, we built a simple model assuming only point light sources and uniform ambient light. In a real environment, light comes from all directions with varying colors and intensities. Light from the sun or from lighting is scattered in the atmosphere or reflected off the surface of an object, then reflected back onto another object, and so on, until the space is filled with light.

古典的な手法についてのページでは、点光源と均一な環境光だけを想定して単純なモデルを構築しました。実際の環境では光はあらゆる方向からやってきます。太陽や照明から出た光が大気で散乱したり物体の表面で反射し、さらにその光が別の物体に反射し、と繰り返し空間は光に満たされます。

In high-quality 3D rendering, a technique generally called ray tracing is used to simulate actual phenomena as closely as possible by following the trajectory of light particles. The higher the accuracy, the more calculations are required, so rendering takes longer.

高品質な3Dレンダリングでは、一般にレイトレーシングと呼ばれる技術を用い、光の粒子の軌跡を忠実に追いかけることで実際の現象を可能な限り再現します。精度が高いほど計算量が多くなるため、レンダリングに時間がかかります。

For simplicity, we will focus on a single sphere placed in the center of the screen. Let's assume that reflections and scattering among other objects have already occurred, and consider only the light coming toward that object. From the point of view of an object, we can think of all surrounding objects as light sources, and the direction from the object determines what kind of light is coming. This light will reflect off the surface of the object, and you will only see the light that happens to be coming into your eyes.

ここでは単純化のため、画面の中央に置かれた球体一個に注目することにします。他の物体の間の反射や散乱はは既に起こったものとし、その物体に向かってくる光だけを考えましょう。ある物体から見ると周囲にある全ての物体が光源だと考えることができ、その物体からの向きによってその方向からどんな光が向かってくるかが決まります。この光が物体の表面で反射し、偶然目に飛び込んできた光だけが見えることになります。

If we further narrow our field of view and focus on a point p on the sphere, we can consider a small hemispherical world as shown in the picture below. From this hemisphere, various lights are directed toward point p. The actual light sources are farther away, but from this point of view, only the direction, color, and intensity of the light are important. How each light reflects and is visible to the eye depends on the orientation of the surface (normal \vec{N}) and its properties, as well as the direction of the eye that perceives the light.

さらに視野を狭めて球面上の一点pに注目すると下の絵のような小さな半球状の世界を考えることができます。この半球からは点pに向けて様々な光が向かってきます。実際の光源はもっと遠くにあるのですが、この点から見れば向きと光の色、強さだけが重要です。それぞれの光がどのように反射し、目に見えるかは表面の向き(法線\vec{N})とその性質、そして光を捉える目の方向に関わっています。

半球から向かってくる光を全て計算することはできませんが、十分な数のサンプルをとって近似することはできます。サンプルする光の向き\omega_1, \omega_2…ごとに物体による目の向き(\omega_0)に対する反射を計算し、平均を取るのがここから先の手法の基本になります。

We cannot calculate all the light coming from the hemisphere, but we can approximate it by taking a sufficient number of samples. Calculating the reflection of the light toward the direction of the eye(\omega_0) for each sample direction of light \omega_1, \omega_2... and taking the average is the basis of the method from here on.

The function that determines the proportion of light reflected at a point *p* from the direction w_1 to the direction of the eye w_0 is called the bidirectional reflectance distribution function (BRDF).

ある点pに置ける光の向きw_1から目の向きw_0に反射する光の割合を求める関数を双方向反射率分布関数(bidirectional reflectance distribution function - BRDF)と呼びます。

The physics of the material 物質の性質

Next, let's examine the objects themselves. As we learned in Specular reflections and diffuse light, there are two types of materials: conductors and dielectrics. Conductors have no diffuse light, and their specular reflection is colored, while dielectrics have diffuse light, and their specular reflection is not colored. In many models, this property is represented by a parameter called metallic, which usually takes values from 1 to 0. Strictly speaking, a material is either a conductor or a dielectric, but intermediate values are also used to reproduce mixed states, such as a metal with a thin layer of paint.

環境の次は描かれる物自体に目を向けてみましょう。鏡面反射と拡散光のページで見たように物質には導体(Conductor)と誘電体 (Dielectric)があり、導体は拡散光(ディフューズ)がなく鏡面反射(スペキュラー)に色がつく、誘電体には拡散光があり、鏡面反射に色が付かないという特徴があります。多くのモデルではこの性質を1から0の値をとる metallic というパラメータで表します。厳密には物質は導体か誘電体かのどちらかなのですが、塗料を薄く塗った金属といった混合状態を再現するのに中間の値も使われます。

Almost any object has fine irregularities (micro-facets) on its surface, and the rougher the surface, the more scattered or blocked the reflected light will be. Think of the demonstration below as a magnified illustration of the situation. As the irregularities are actually invisibly fine-grained, this is usually processed statistically. The parameter that describes this is usually called roughness.

ほぼ全ての物体には表面に細かな凹凸(マイクロファセット)があり、表面が粗いほど反射光が散乱したり遮られたりします。下のデモはこの様子を拡大したものだと考えてください。凹凸は目に見えないくらい細かく無数にあるので実際には統計的に処理します。表面の粗さを表すパラメータは大抵 roughness と呼ばれます。

Energy Conservation エネルギーの保存

Another physically important point is the law of conservation of energy. Unless the object itself is emitting light, the sum of outgoing light, i.e., the sum of diffuse and specular components, is always less than the incoming light (some of the light energy is absorbed and becomes heat).

もう1つ物理的に重要な点にエネルギー保存の法則があります。物体自体が発光していない限り出ていく光、つまりディフューズ成分とスペキュラー成分の和は入射光よりも必ず少なくなります(光のエネルギーの一部は吸収されて熱になります)。

Diffuse Light ディフューズ(拡散光)

We will start with the diffuse component here because it is simpler. We will use Lambert's model, as described in the Classical Methods page, as the BDRF for the diffuse component. If you are interested, the Filament page touches on other models used by Disney and the Unreal Engine.

ディフューズ成分の方が簡単なのでこちらから始めます。ディフューズ成分はBDRFとして古典的な手法のページで説明したランバートのモデルを使います。FilamentのページにはDisneyやUnreal Engineで使われているモデルも紹介されているので興味があれば参考にしてください。

The demo below shows a red ball rendered only with the diffuse component. The bottom part is darker because the blue ambient light combined with the color of the red object makes it look blackish. It looks a little flat since it is illuminated from all directions. Let's see how it changes with the specular component added.

下のデモは赤いボールをディフューズ成分だけでレンダリングしています。下の方が暗いのは青い環境光と赤い物体の色がかけ合わさって黒っぽく見えるからです。全方向から光が当たっているので少しフラットな印象ですがここにスペキュラー成分を入れるとどうなるか見ていきましょう。

Specular Reflection スペキュラー(鏡面反射)

Specular BDRF スペキュラーのBDRF

For the specular component, a model called Cook-Torrance is often used as a BRDF, and it looks like the equation below.

スペキュラー成分のBDRFでよく使われるのはCook-Torranceというモデルで下記の式で表されます。

\frac{DFG}{4(\omega_0 \cdot n)(\omega_i \cdot n)}

The denominator is determined by the direction of the line of sight (\omega_0), the direction of the light source (\omega_i), and the normal (n). Let's look at what D, F, and G do in the numerator.

分母は視線の向き(\omega_0)、光源の向き(\omega_i)、法線(n)によって決まります。分子のDFGが何をしているか見てみましょう。

D(normal distribution function)

D is the normal distribution function, indicating how well the fine irregularities (micro-facets) align with the orientation of the halfway vector (the vector halfway between the direction of the light and the direction of the viewpoint). This is the same concept as seen on the classical rendering page, and the results are very similar. In the demo below, moving the mouse left or right changes the roughness of the surface.

DはNormal distribution function と呼ばれます。表面の細かな凹凸の向きがどれだけ、halfway vector(光源の方向と視点の方向の中間に当たるベクトル)の向きとそろっているを表します。これは古典的レンダリングのページで見たのと同じコンセプトで、結果もよく似ています。下のデモでは左右にマウスを動かすことで表面の粗さ(roughness)が変化します。

G(geometry function)

G is the geometry function, which represents the effect of micro-facets casting shadows around. Notice how the rougher the surface becomes (move the mouse to the right), the darker the area where the light hits the surface from the side becomes.

Gはgeometry functionで表面の凹凸が周りに影を落とす効果を再現します。下のデモで表面が粗くなる(マウスを右に動かす)ほど光が斜めから当たる部分が暗くなるのを見てください。

F(fresnel equation)

F is the Fresnel equation that we covered on the Reflection and Refraction page. It determines the amount of light that is specularly reflected based on the angle of incidence and refractive indices. To make it easier to observe the effect, the demo below shows both cases with and without a background.

Fは反射と屈折のページで見たフレネルの式です。入射角と屈折率から鏡面反射する光の割合を求めます。効果が分かりやすいよう、下のデモでは背景がある場合とない場合をそれぞれ表示しています。

Combining with Diffuse ディフューズと合わせる

The demo below shows a model that combines specular and diffuse lighting, illuminated by four point lights. The concepts explained above are reflected quite directly in the code. Try following the functions one by one. Moving the mouse left or right changes the roughness, and up or down changes the metallic and the material color.

下のデモはスペキュラーとディフューズを合わせたモデルを4つの点光源で照らしたものです。上で説明した概念がかなりダイレクトにコードに反映されているのでひとつひとつ関数を追って見ましょう。マウスを左右に動かすと roughness が、上下に動かすと metallic とマテリアルの色が値が変化します。

Fresnel's equation can also be used to find the total amount of specular components. To get the percentage of the diffuse component, subtract the specular component from 1.

フレネルの式はスペキュラー成分の総量を求めるのに使うこともできます。スペキュラー成分を1から引いたものがディフューズ成分の割合になります。

vec3 F    = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 kS = F; // Specular
vec3 kD = vec3(1.0) - kS; // Diffuse
kD *= 1.0 - metallic; // Reduce the diffuse component according to the metallic parameter

Sampling the environment light 環境光のサンプリング

To reflect environment light, we need to sample a wide range of light, as is the case with diffusion.

環境光を反映するにはディフューズの時と同じく広い範囲の光をサンプリングする必要があります。

In the LearnOpenGL.com implementation, a function called ImportanceSampleGGX is responsible for adjusting the sampling according to the roughness of the surface, which uses the Hammersley point set. This may sound quite incomprehensible, so let's visualize it. This is only a technical detail, and other techniques can be used. The important thing to remember is that the rougher the surface, the blurrier the reflected image will appear.

LearnOpenGL.comの実装では、表面の粗さに応じてサンプリングを調整するためにImportanceSampleGGXという関数が使用されています。この関数では、Hammersley point setが使用されています。何を言っているのかわからないので、視覚化してみましょう。これはあくまで技術的なディテールであるため、他の手法を使用することもできます。重要なのは、粗い表面ほど反射した像がボケて見えるということです。

The Hammersley point set can be used to generate points scattered as evenly as possible across the plane, as demonstrated below.

Hammersley point setを使うと下のデモのように平面上にできるだけ均等に散らばった点を生成することができます。

In importanceSampleGGX, these points are laid out on a hemisphere based on the roughness value. The smaller the roughness, the more concentrated the points are, while the larger the roughness, the more evenly spread out the points become.

importanceSampleGGXではこれらの点をroughnessの値によって半球上にレイアウトしています。roughnessが小さいほど点が中央に集まり、大きければ広く均等に拡散する様子がわかります。

The demo below reflects this. The D, G, and F functions are mixed up and might be harder to follow since the roughness is taken into account at the time of sampling, but the basic idea is the same.

これを反映したものが下のデモです。サンプリングの時点でroughnessが考慮されているので、上のDGFの関数が混ぜ合わさったようになり読みにくいかもしれませんがが基本的な考え方は同じです。

This page has become quite technical; there is endless stuff to learn as new methods are constantly being developed in the field of 3D and game development. In many cases, you will be able to rely on features implemented in tools and libraries, but even in those cases, I hope this page provides some intuition on what is happening.

このページは、かなり技術的な内容になってしまいました。3Dやゲーム開発の分野では常に新しい手法が開発されており、学ぶことは無限にあります。多くの場合はツールやライブラリに実装された機能を頼ることができると思いますが、その場合でも、このページが何が起こっているのかを理解する助けになればと思います。

Light and 2D Graphics 光と2Dグラフィックス

Index


@kynd Twitter Instagram Vimeo Threads

Discussion