To render a 3D scene using ray marching, we need to shoot a ray for each pixel. Remember how projection works. By selecting a point on the screen (a pixel), and drawing a ray from the viewpoint, we can determine if it hits an object and decide what should be drawn on that pixel. Using a shader, we can process all the pixels in parallel to complete the whole image.

3Dシーンをレンダリングするには、それぞれのピクセルに対してレイを飛ばす必要があります。プロジェクションの原理を思い出してください。画面上の点(ピクセル)を選んで視点からレイを伸ばし、物体に当たるかどうかを判定してそのピクセルに何を描くかを決めます。シェーダーを使うと、すべてのピクセルを並列に処理して全体のイメージを完成させることができます。

Screenshot 2023-10-22 at 3.14.24 PM.png

The following example demonstrates the idea. The starting position of the ray and the direction are determined by the viewpoint (eye) and the position of the current pixel (crd).

下のデモでこのアイデアを実演します。レイの始点と方向は、視点(eye)と現在のピクセルの位置(crd)によって決まります。

vec3 eye = vec3(0.0, 0.0, -2.5);
vec3 rayDir = normalize(vec3(crd, 0.0) - eye);

The raymarch function is the main part of this demo, in which we move a point along the ray and use the SDF (signed distance function) to check if it gets close enough to the surface. The function returns the distance if it goes below the threshold, or -1.0 otherwise.

raymarch関数がこのデモのメインで、点をレイに沿って移動させ、SDF(符号付き距離関数)を使って、表面に十分に近づいたかをチェックします。この関数は、距離が閾値を下回る場合その値を返し、それ以外の場合は-1.0を返します。

float raymarch(vec3 eye, vec3 rayDir) {
float dist = 0.0;
float threshold = 0.005;
for(int i = 0 ; i < 16 ; ++i) {
float d = SDF(eye + rayDir * dist);
if(d < threshold) { return dist; }
dist += d;
}
return -1.0;
}

On the dark gray background, the shader only turns the pixel white if the ray intersects with the sphere.

シェーダーは暗いグレーの背景の上で、レイが球体と交差する場合にだけピクセルを白くします。

https://codepen.io/kynd/pen/OJdJoNg?editors=0010

Finding the normal

法線を見つける