《光线跟踪算法技术》代码4.1解释

Table of Contents

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

首先上代码:

void World::render_scene(void) const {
    RGBColor pixel_color;
    Ray ray;
    float zw = 100.0;
    int n = (int)sqrt((float)vp.num_samples);
    Point2D pp; // sample point on a pixel

    open_window(vp.hres,vp.vres);
    ray.d = Vector3D(0,0,-1);
 
    for (int r = 0; r < vp.vres; r++)       // up
        for (int c = 0; c < vp.hres; c++) { // across
            pixel_color = black; 

            for (int p = 0; p < n; p++)         // up pixel
                for (int q = 0; q < n; q++) {   // across pixel
                    pp.x = vp.s * (c - 0.5 * vp.hres + (q + 0.5) / n); 
                    pp.y = vp.s * (r - 0.5 * vp.vres + (p + 0.5) / n);
                    ray.o = Point3D(pp.x,pp.y,zw);
                    pixel_color += tracer_ptr->trace_ray(ray);
                }

            pixel_color /= vp.num_samples;
            display_pixel(r, c, pixel_color);
        } 
}

假设令采样列与采样行值n为5,vp.vresvp.hres为100,令像素大小vp.s为1,那么,当r为0,c为0时,上述代码中,代入具体数值后,用来进行采样的双重循环的代码段如下:

for (int p = 0; p < n; p++)         // up pixel
    for (int q = 0; q < n; q++) {   // across pixel
        pp.x = -50 + (q + 0.5)/5;
        pp.y = -50 + (p + 0.5)/5;
        ray.o = Point3D(pp.x,pp.y,zw);
        pixel_color += tracer_ptr->trace_ray(ray);
    }

pq取值如下表时,对应的pp.xpp.y的取值如下:

pp.x\pp.y 0 1 2 3 4
0 (-49.9,-49.9) (-49.7,-49.9) (-49.5,-49.9) (-49.3,-49.9) (-49.1,-49.9)
1 (-49.9,-49.7) (-49.7,-49.7) (-49.5,-49.7) (-49.3,-49.7) (-49.1,-49.7)
2 (-49.9,-49.5) (-49.7,-49.5) (-49.5,-49.5) (-49.3,-49.5) (-49.1,-49.5)
3 (-49.9,-49.3) (-49.7,-49.3) (-49.5,-49.3) (-49.3,-49.3) (-49.1,-49.3)
4 (-49.9,-49.1) (-49.7,-49.1) (-49.5,-49.1) (-49.3,-49.1) (-49.1,-49.1)

而如果不进行均匀采样的话,当cr为0时,对应的ray.o的x,y分量为 (-49.5,-49.5) 。即程序清单3.12中的计算方式。也即对应于表格中的pp.xpp.y都等于2时的取值,简而言之,就是说,均匀采样,就是把采样格子再划分得细点儿。如下图所示:

如果不执行均匀采样的话,那么向(-49.5,-49.5)处投射光线,是无法和红色的三角形相交的,对应的像素点采样的就不会产生着色。而如果使用均匀采样的话,将会对原来的“一格”像素格,再划分25格进行光线相交检测显然,有部分的“细分像素格”是和红色三角形相交的,故而,这个像素格应该会产生着色。颜色值就是这25个颜色格的颜色和的平均值。

程序清单3.12中的计算方式的代码如下:

void World::render_scene(void) const{
    RGBColor pixel_color;
    Ray ray;
    double zw = 100.0;      // hard wired int
    double x , y;

    open_window(vp.hres,vp.vres);
    ray.d = Vector3D(0,0,-1);
    
    for(int r = 0; r < vp.vres; r++)
        for(int c = 0; c <= vp.hres; c++){
            x = vp.s * (c-0.5*(vp.hres-1.0));
            y = vp.s * (c-0.5*(vp.vres-1.0));
            ray.o = Point3D(x,y,zw);
            pixel_color = trace_ptr->trace_ray(ray);
            display_pixel(r,c,pixel_color);
        }
}
kumakoko avatar
kumakoko
pure coder
comments powered by Disqus