Q102:光线追踪场景(5)——驭龙台

198 篇文章 12 订阅
195 篇文章 27 订阅

0,引入

“驭龙台”这个名字是后来起的,原本只是打算设计这么一个场景,如下图:
这里写图片描述

先申明一点:“驭龙台”场景中的大部分图形都是有磨边的楔形构成。

对于场景中的台阶、房顶、墙面,原本只是打算建差不多和上图中能看到的这么一个范围(对应phi0,phi1),后来把phi0、phi1扩充到了整个圆周。
所以,远看这个场景是这么个样子:
这里写图片描述
从这个视角看时,咱就决定将这个场景命名为“驭龙台”啦!
至于为什么起这个名?这个名的含义是什么?
木有深究,只是感觉很厉害的样子!!!

接下来,我们将分别看看场景中的各个部分是怎么设置和创建的。
主要是要注意:各个“基本图形”的参数设置,以便和谐地构成整个场景。

1,第一部分:中间的圆台

这一部分又是有三部分组成:最下面的Rosette花环、磨边的box、矩形面。

1.1 Rossette花环

这个和“Q104:怎么用ray tracing画基于磨边楔形的“花环(Rosette)””是一样的。之前的链接:
http://blog.csdn.net/libing_zeng/article/details/70194670

Phong材质,大理石纹理。

场景中创建这么一个设置有随机大理石纹理的Rosette的相关代码如下:

////////////////////////////////////////floor, Rosette///////////////////////////////////////

    // rosette parameters

    int     num_rings = 3;      // maximum of 6
    float   hole_radius = 1.0;
    float   ring_width = 1.0;
    float   rb = 0.025;         // bevel radius
    float   y0 = -0.1;          // minimum y value
    float   y1 = 0.1;           // minimum y value


    Rosette* rosette_floor_ptr = new Rosette(num_rings, hole_radius, ring_width, rb, y0, y1);

    // put a different random marble texture on each wedge

    // ramp image:

    Image* image_floor_ptr = new Image;
    image_floor_ptr->read_ppm_file(".\\TextureFiles\\ppm\\BlueMarbleRamp.ppm");

    // marble texture parameters

    int floor_num_octaves = 4;
    float floor_lacunarity = 2.0;
    float floor_gain = 0.5;
    float floor_perturbation = 3.0;

    int floor_num_objects = rosette_floor_ptr->get_num_objects();

    for (int j = 0; j < floor_num_objects; j++) {

        // noise:

        CubicNoise* noise_floor_ptr = new CubicNoise;
        noise_floor_ptr->set_num_octaves(floor_num_octaves);
        noise_floor_ptr->set_gain(floor_gain);          // not relevant when num_octaves = 1
        noise_floor_ptr->set_lacunarity(floor_lacunarity);     // not relevant when num_octaves = 1


        // marble texture:

        FBmTextureRamp* marble_floor_ptr = new FBmTextureRamp(image_floor_ptr);
        marble_floor_ptr->set_noise(noise_floor_ptr);
        marble_floor_ptr->set_perturbation(floor_perturbation);


        // transformed marble texture

        InstanceTexture* wedge_marble_floor_ptr = new InstanceTexture(marble_floor_ptr);
        set_rand_seed(j * 10);
        wedge_marble_floor_ptr->scale(0.25);
        wedge_marble_floor_ptr->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
        wedge_marble_floor_ptr->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
        wedge_marble_floor_ptr->rotate_z(45.0 * (2.0 * rand_float() - 1.0));
        wedge_marble_floor_ptr->translate(10.0 * (2.0 * rand_float() - 1.0), 20.0 * (2.0 * rand_float() - 1.0), 30.0 * (2.0 * rand_float() - 1.0));

        // material:

        SV_Phong* sv_phong_floor_ptr = new SV_Phong;
        sv_phong_floor_ptr->set_ka(0.25);
        sv_phong_floor_ptr->set_kd(0.75);
        sv_phong_floor_ptr->set_cd(wedge_marble_floor_ptr);
        sv_phong_floor_ptr->set_ks(0.1);
        sv_phong_floor_ptr->set_exp(20.0);

        rosette_floor_ptr->store_material(sv_phong_floor_ptr, j);   // store material in the specified wedge
    }

    rosette_floor_ptr->setup_cells();
    add_object(rosette_floor_ptr);

1.2 磨边的box

花环floor之上是四个磨边的box组成的封闭框架。

Phong材质,4号砂岩纹理。

创建这么四个磨边的box的相关代码如下:


    // noise:

    CubicNoise* noise_bevel_b_platform_ptr = new CubicNoise;
    noise_bevel_b_platform_ptr->set_num_octaves(6);
    noise_bevel_b_platform_ptr->set_gain(2);            // not relevant when num_octaves = 1
    noise_bevel_b_platform_ptr->set_lacunarity(0.5);     // not relevant when num_octaves = 1

    // ramp image:

    Image* image_bevel_b_platform_ptr = new Image;
    image_bevel_b_platform_ptr->read_ppm_file(".\\TextureFiles\\ppm\\sandstone_ramp4.ppm");

    // marble texture:

    FBmTextureRamp* sandstone_bevel_b_platform_ptr = new FBmTextureRamp(image_bevel_b_platform_ptr);
    sandstone_bevel_b_platform_ptr->set_noise(noise_bevel_b_platform_ptr);
    sandstone_bevel_b_platform_ptr->set_perturbation(0.1);


    // transformed sandstone texture

    InstanceTexture* wedge_sandstone_bevel_b_platform_ptr = new InstanceTexture(sandstone_bevel_b_platform_ptr);
    set_rand_seed(20);
    wedge_sandstone_bevel_b_platform_ptr->scale(0.25);
    wedge_sandstone_bevel_b_platform_ptr->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
    wedge_sandstone_bevel_b_platform_ptr->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
    wedge_sandstone_bevel_b_platform_ptr->rotate_z(45.0 * (2.0 * rand_float() - 1.0));
    wedge_sandstone_bevel_b_platform_ptr->translate(10.0 * (2.0 * rand_float() - 1.0), 20.0 * (2.0 * rand_float() - 1.0), 30.0 * (2.0 * rand_float() - 1.0));


    // material:

    SV_Phong* sv_phong_bevel_b_platform_ptr = new SV_Phong;
    sv_phong_bevel_b_platform_ptr->set_ka(0.25);
    sv_phong_bevel_b_platform_ptr->set_kd(0.75);
    sv_phong_bevel_b_platform_ptr->set_cd(wedge_sandstone_bevel_b_platform_ptr);
    sv_phong_bevel_b_platform_ptr->set_ks(0.1);
    sv_phong_bevel_b_platform_ptr->set_exp(20.0);

    BeveledBox* bevel_b_platform_ptr1 = new BeveledBox(Point3D(-2.9, 0.1,-1.9), Point3D(-2.7, 0.3,  1.9), 0.1);
    bevel_b_platform_ptr1->set_material(sv_phong_bevel_b_platform_ptr);
    add_object(bevel_b_platform_ptr1);
    BeveledBox* bevel_b_platform_ptr2 = new BeveledBox(Point3D( 2.7, 0.1,-1.9), Point3D( 2.9, 0.3,  1.9), 0.1);
    bevel_b_platform_ptr2->set_material(sv_phong_bevel_b_platform_ptr);
    add_object(bevel_b_platform_ptr2);
    BeveledBox* bevel_b_platform_ptr3 = new BeveledBox(Point3D(-2.7, 0.1, 1.7), Point3D( 2.7, 0.3,  1.9), 0.1);
    bevel_b_platform_ptr3->set_material(sv_phong_bevel_b_platform_ptr);
    add_object(bevel_b_platform_ptr3);
    BeveledBox* bevel_b_platform_ptr4 = new BeveledBox(Point3D(-2.7, 0.1,-1.9), Point3D( 2.7, 0.3, -1.7), 0.1);
    bevel_b_platform_ptr4->set_material(sv_phong_bevel_b_platform_ptr);
    add_object(bevel_b_platform_ptr4);

这里需要注意的是:用于创建BeveledBox对象的两个顶点(第一个顶点是“最小顶点”,第二个顶点是“最大顶点”。第一个顶点的三个坐标值必须都比第三个顶点坐标的三个值药效。)

1.3 矩形

四个磨边的box组成的封闭框架中间嵌这一个矩形面。类似于“镶着边框的镜子”

glossy材质,wrapped的噪声纹理。
glossy的指数为1000,矩形面中的镜像比较模糊。

创建矩形的相关代码如下:

    Rectangle* rectangle_platform_ptr = new Rectangle(Point3D(-2.7, 0.2, 1.7), Vector3D(5.4, 0, 0), Vector3D(0, 0, -3.4));

    // noise:

    CubicNoise* noise_rectangle_platform_ptr = new CubicNoise;
    noise_rectangle_platform_ptr->set_num_octaves(8);
    noise_rectangle_platform_ptr->set_gain(0.5);
    noise_rectangle_platform_ptr->set_lacunarity(8.0);

    FBmTextureWrapped* texture_rectangle_platform_ptr = new FBmTextureWrapped(noise_rectangle_platform_ptr);
    texture_rectangle_platform_ptr->set_expansion_number(8.0);
    texture_rectangle_platform_ptr->set_color(0.7, 1.0, 0.5);   // light green
    texture_rectangle_platform_ptr->set_min_value(0.0);
    texture_rectangle_platform_ptr->set_max_value(1.0);

    // textured material:

    float exp_rectangle_platform = 1000.0;
    SV_GlossyReflector* sv_glossy_rectangle_platform_ptr = new SV_GlossyReflector;
    sv_glossy_rectangle_platform_ptr->set_samples(num_samples, exp_rectangle_platform);
    sv_glossy_rectangle_platform_ptr->set_ka(0.1);
    sv_glossy_rectangle_platform_ptr->set_kd(0.25);
    sv_glossy_rectangle_platform_ptr->set_ks(0.1);
    sv_glossy_rectangle_platform_ptr->set_exp(exp_rectangle_platform);
    sv_glossy_rectangle_platform_ptr->set_cd(texture_rectangle_platform_ptr);
    sv_glossy_rectangle_platform_ptr->set_kr(0.75);
    sv_glossy_rectangle_platform_ptr->set_exponent(exp_rectangle_platform);
    sv_glossy_rectangle_platform_ptr->set_cr(new ConstantColor(white));

    Instance* instance_sc_rectangle_platform_ptr = new Instance(rectangle_platform_ptr);
    instance_sc_rectangle_platform_ptr->set_material(sv_glossy_rectangle_platform_ptr);
    add_object(instance_sc_rectangle_platform_ptr);

2,第二部分:龙

“龙”卧在在矩形面上。

Phong材质,大理石纹理。

“龙”模型的创建和“Q102:光线追踪场景(2)——PLYs(多种模型汇集)”是一样的。之前的链接如下:
http://blog.csdn.net/libing_zeng/article/details/70176906

创建“龙”模型的相关代码如下:

////////////////////////////////////////dragon////////////////////////////////////////////////

    char* file_dragon_name = ".\\PLYFiles\\dragon.ply";
    Grid* grid_dragon_ptr = new Grid(new Mesh);
    grid_dragon_ptr->read_smooth_triangles(file_dragon_name);
    grid_dragon_ptr->setup_cells();

    // noise:

    CubicNoise* noise_dragon_ptr = new CubicNoise;
    noise_dragon_ptr->set_num_octaves(6);
    noise_dragon_ptr->set_gain(0.5);
    noise_dragon_ptr->set_lacunarity(2.0);

    // ramp image:

    Image* image_dragon_ptr = new Image;
    image_dragon_ptr->read_ppm_file(".\\TextureFiles\\ppm\\BlueMarbleRamp.ppm");

    // marble texture:

    FBmTextureRamp* marble_dragon_ptr = new FBmTextureRamp(image_dragon_ptr);
    marble_dragon_ptr->set_noise(noise_dragon_ptr);
    marble_dragon_ptr->set_perturbation(4.0);

    InstanceTexture* it_dragon_ptr = new InstanceTexture(marble_dragon_ptr);
    it_dragon_ptr->scale(0.05);
//  it_dragon_ptr->rotate_z(110);
//  it_dragon_ptr->translate(1.0, 4.0, 0.0);


    // material:

    SV_Phong* sv_phong_dragon_ptr = new SV_Phong;
    sv_phong_dragon_ptr->set_ka(0.25);
    sv_phong_dragon_ptr->set_kd(0.75);
    sv_phong_dragon_ptr->set_cd(it_dragon_ptr);
    sv_phong_dragon_ptr->set_ks(0.1);
    sv_phong_dragon_ptr->set_exp(20.0);


    Instance* instance_dragon_ptr = new Instance(grid_dragon_ptr);
    instance_dragon_ptr->scale(20, 10, 20);
    instance_dragon_ptr->translate(0, -0.3, 0);
    instance_dragon_ptr->set_material(sv_phong_dragon_ptr);

    add_object(instance_dragon_ptr);

3,第三部分:柱子(pillars)

这里写图片描述
“柱子”是由若干个“Rosette”叠加而成的。
Phong材质,3号砂岩纹理

相关参数:
柱子底的位置y0_p、柱子顶的位置y1_p、组成柱子的Rosette的个数rosette_num_pillar、磨边Rosette的三个参数(hole_radius_p、 ring_width_p、rb_p)、场景中柱子的根数pillar_num、所有柱子的起始角度和终止角度(pillar_angle_start、pillar_angle_end)。

由如上参数,我们可以计算:
1,两根柱子间的角度范围pillar_angle_width = (pillar_angle_end - pillar_angle_start) / pillar_num;
2,单个Rosette的高度rosette_height = (y1_p - y0_p) / rosette_num_pillar;
3,第pi跟柱子对应的角度phi0_pillar = (pillar_angle_start + pillar_angle_width * pi) * PI_ON_180;
从而,可以计算得到每根柱子位置的x、z坐标:
pillar_center_x = - (hole_radius_p + ring_width_p + r0_s) * sin((phi0_pillar-1e-6));
pillar_center_z = (hole_radius_p + ring_width_p + r0_s) * cos((phi0_pillar-1e-6));
4,单根柱子中第ri个Rosette的上下底的位置:
rosette_y0_temp = y0_p + ri*rosette_height;
rosette_y1_temp = rosette_y0_temp + rosette_height;
这样创建Rosette对象所需的参数就齐啦。

(3、4中对应两个for循环:3中根据柱子编号pi循环;4中根据单个柱子中Rosette的编号循环)。

创建“柱子”的相关代码如下:(随机砂岩纹理的设置和Rosette中随机大理石纹理的设置相似)

////////////////////////////////////////pillar, Rosette///////////////////////////////////////

    // rosette parameters

    int     num_rings_p = 1;        // maximum of 6
    float   hole_radius_p = 0.05;
    float   ring_width_p = 0.25;
    float   rb_p = 0.02;            // bevel radius
    float   y0_p = 0.3;         // minimum y value
    float   y1_p = 3.7;         // minimum y value


    int pillar_num = 4;
    double pillar_angle_start = -45;
    double pillar_angle_end = 315;
    double pillar_angle_width = (pillar_angle_end - pillar_angle_start) / pillar_num;

    int rosette_num_pillar = 20;
    double rosette_height = (y1_p - y0_p) / rosette_num_pillar;

    for (int pi=0; pi<=pillar_num; pi++) {
        double phi0_pillar = (pillar_angle_start + pillar_angle_width * pi) * PI_ON_180;

        double pillar_center_x = - (hole_radius_p + ring_width_p + r0_s) * sin((phi0_pillar-1e-6));
        double pillar_center_z =   (hole_radius_p + ring_width_p + r0_s) * cos((phi0_pillar-1e-6));

        for (int ri=0; ri<rosette_num_pillar; ri++) {
            double rosette_y0_temp = y0_p + ri*rosette_height;
            double rosette_y1_temp = rosette_y0_temp + rosette_height;

            Rosette* rosette_pillar_ptr = new Rosette(num_rings_p, hole_radius_p, ring_width_p, rb_p, rosette_y0_temp, rosette_y1_temp);

            // put a different random marble texture on each wedge

            // ramp image:

            Image* image_rp_ptr = new Image;
            image_rp_ptr->read_ppm_file(".\\TextureFiles\\ppm\\sandstone_ramp3.ppm");

            // marble texture parameters

            int num_octaves_rp = 4;
            float lacunarity_rp = 2.0;
            float gain_rp = 0.5;
            float perturbation_rp = 0.1;

            int num_objects_rp = rosette_pillar_ptr->get_num_objects();

            for (int rpj = 0; rpj < num_objects_rp; rpj++) {

                // noise:

                CubicNoise* noise_rp_ptr = new CubicNoise;
                noise_rp_ptr->set_num_octaves(num_octaves_rp);
                noise_rp_ptr->set_gain(gain_rp);            // not relevant when num_octaves = 1
                noise_rp_ptr->set_lacunarity(lacunarity_rp);     // not relevant when num_octaves = 1


                // marble texture:

                FBmTextureRamp* sandstone_rp_ptr = new FBmTextureRamp(image_rp_ptr);
                sandstone_rp_ptr->set_noise(noise_rp_ptr);
                sandstone_rp_ptr->set_perturbation(perturbation_rp);


                // transformed marble texture

                InstanceTexture* wedge_sandstone_rp_ptr = new InstanceTexture(sandstone_rp_ptr);
                set_rand_seed(rpj * 10);
                wedge_sandstone_rp_ptr->scale(0.25);
                wedge_sandstone_rp_ptr->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
                wedge_sandstone_rp_ptr->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
                wedge_sandstone_rp_ptr->rotate_z(45.0 * (2.0 * rand_float() - 1.0));
                wedge_sandstone_rp_ptr->translate(10.0 * (2.0 * rand_float() - 1.0), 20.0 * (2.0 * rand_float() - 1.0), 30.0 * (2.0 * rand_float() - 1.0));

                // material:

                SV_Phong* sv_phong_rp_ptr = new SV_Phong;
                sv_phong_rp_ptr->set_ka(0.25);
                sv_phong_rp_ptr->set_kd(0.75);
                sv_phong_rp_ptr->set_cd(wedge_sandstone_rp_ptr);
                sv_phong_rp_ptr->set_ks(0.1);
                sv_phong_rp_ptr->set_exp(20.0);

                rosette_pillar_ptr->store_material(sv_phong_rp_ptr, rpj);   // store material in the specified wedge
            }

            rosette_pillar_ptr->setup_cells();

            Instance* instance_rp_ptr = new Instance(rosette_pillar_ptr);
            instance_rp_ptr->translate(pillar_center_x, 0, pillar_center_z);
            add_object(instance_rp_ptr);
        }
    }

4,第四部分:门

这里写图片描述

整个墙面就是由若干个这样的门拼接而成。

如上图,每一扇门是由很多个“基本部分”组成。
每一个“基本部分”都是一个“磨边的楔形(Beveled Wedge)”。
只是每个磨边楔形的形状、大小、材质、纹理不一样。

每一扇门被称为一个“unit”。假设每个unit为5个单位长度,那么设置该unit中每个wedge的相关参数如下:

    double _wall_width      = 0.5;
    double _frame_width     = 0.1;
    double _window_width    = 0.8;
    double _door_width      = 0.95;
    double _gap_width       = 0.1;
    double unit             = 5.0; // (wall+frame+window+frame+door)*2+gap


    double _wall_width_rate     = _wall_width    / unit;
    double _frame_width_rate    = _frame_width   / unit;
    double _window_width_rate   = _window_width  / unit;
    double _door_width_rate     = _door_width    / unit;
    double _gap_width_rate      = _gap_width     / unit;

    int unit_num = 10;
    double angle_start = 0; // -90,270
    double angle_end = 360;
    double unit_angle_width = (angle_end - angle_start) / unit_num;

    double _wall_angle_width    = _wall_width_rate      * unit_angle_width;
    double _frame_angle_width   = _frame_width_rate     * unit_angle_width;
    double _window_angle_width  = _window_width_rate    * unit_angle_width;
    double _door_angle_width    = _door_width_rate      * unit_angle_width;
    double _gap_angle_width     = _gap_width_rate       * unit_angle_width;

    double y10_unit = 0.3;          // bottom of the unit
    double y11_unit = 3.7;          // top of the unit
    double y20_unit = 0.3;          // the height of frame is 0.1
    double y21_unit = 0.4;
    double y30_unit = 0.4;          // the height of window is 1
    double y31_unit = 1.4;
    double y40_unit = 1.4;
    double y41_unit = 1.5;
    double y50_unit = 1.5;
    double y51_unit = 2.5;
    double y60_unit = 2.5;
    double y61_unit = 2.6;
    double y70_unit = 2.6;
    double y71_unit = 3.6;
    double y80_unit = 3.6;
    double y81_unit = 3.7;

    double r10_unit = 6.9;          // inner radius for phong material objects: wall, frame
    double r11_unit = 7.0;          // outer radius for phong material objects: wall, frame
    double r20_unit = 6.94;         // inner radius for glossy material objects: door, window
    double r21_unit = 6.96;         // outer radius for glossy material objects: door, window
    double rb1_unit  = 0.01;        // beveled radius for phong material objects
    double rb2_unit  = 0.005;       // beveled radius for glossy material objects

前面已经提到过,每个unit中涉及到各种材质和纹理:
墙面:Phong材质,1号砂岩纹理;
纵向门框:Phong材质,纵向木纹纹理;
横向门框:Phong材质,横向木纹纹理;
门体、窗户:glossy材质(指数设置为100000),无纹理;

相关代码如下:


//---------------------------------------------wall material-----------------------------------

    // noise:

    CubicNoise* noise_wall_ptr1 = new CubicNoise;
    noise_wall_ptr1->set_num_octaves(6);
    noise_wall_ptr1->set_gain(0.5);         // not relevant when num_octaves = 1
    noise_wall_ptr1->set_lacunarity(2.0);     // not relevant when num_octaves = 1

    // ramp image:

    Image* image_wall_ptr1 = new Image;
//    image_wall_ptr1->read_ppm_file(".\\TextureFiles\\ppm\\BlueMarbleRamp.ppm");
    image_wall_ptr1->read_ppm_file(".\\TextureFiles\\ppm\\sandstone_ramp1.ppm");

    // marble texture:

    FBmTextureRamp* marble_wall_ptr1 = new FBmTextureRamp(image_wall_ptr1);
    marble_wall_ptr1->set_noise(noise_wall_ptr1);
    marble_wall_ptr1->set_perturbation(0.2);

    InstanceTexture* it_wall_ptr1 = new InstanceTexture(marble_wall_ptr1);
    it_wall_ptr1->scale(0.5);
    it_wall_ptr1->rotate_z(110);
    it_wall_ptr1->translate(1.0, 4.0, 0.0);

    // material:

    SV_Phong* sv_phong_wall_ptr1 = new SV_Phong;
    sv_phong_wall_ptr1->set_ka(0.25);
    sv_phong_wall_ptr1->set_kd(0.75);
    sv_phong_wall_ptr1->set_cd(it_wall_ptr1);
    sv_phong_wall_ptr1->set_ks(0.1);
    sv_phong_wall_ptr1->set_exp(20.0);

//---------------------------------------------vertical frame material-----------------------------------

    // wood texture

    RGBColor frame_light_color1(0.8274, 0.5059, 0.2392);
    RGBColor frame_dark_color1(0.05);

    Wood* wood_frame_ptr1 = new Wood(frame_light_color1, frame_dark_color1);
    wood_frame_ptr1->set_grainy(1.0);
    wood_frame_ptr1->set_ringy(1.0);

    InstanceTexture* transformed_wood_frame_ptr1 = new InstanceTexture(wood_frame_ptr1);
    set_rand_seed(40);
    transformed_wood_frame_ptr1->scale(0.4);
    transformed_wood_frame_ptr1->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
    transformed_wood_frame_ptr1->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
    transformed_wood_frame_ptr1->rotate_z(45.0 * (2.0 * rand_float() - 1.0));

    // material:

    SV_Phong* sv_phong_frame_ptr1 = new SV_Phong;
    sv_phong_frame_ptr1->set_ka(0.25);
    sv_phong_frame_ptr1->set_kd(0.75);
    sv_phong_frame_ptr1->set_cd(transformed_wood_frame_ptr1);
    sv_phong_frame_ptr1->set_ks(0.1);
    sv_phong_frame_ptr1->set_exp(20.0);

//---------------------------------------------horizontal frame material-----------------------------------

    // wood texture

    RGBColor frame_light_color2(0.8274, 0.5059, 0.2392);
    RGBColor frame_dark_color2(0.05);

    Wood* wood_frame_ptr2 = new Wood(frame_light_color2, frame_dark_color2);
    wood_frame_ptr2->set_grainy(1.0);
    wood_frame_ptr2->set_ringy(1.0);

    InstanceTexture* transformed_wood_frame_ptr2 = new InstanceTexture(wood_frame_ptr2);
    set_rand_seed(80);
    transformed_wood_frame_ptr2->scale(0.8);
    transformed_wood_frame_ptr2->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
    transformed_wood_frame_ptr2->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
    transformed_wood_frame_ptr2->rotate_z(45.0 * (2.0 * rand_float() - 1.0));

    // material:

    SV_Phong* sv_phong_frame_ptr2 = new SV_Phong;
    sv_phong_frame_ptr2->set_ka(0.25);
    sv_phong_frame_ptr2->set_kd(0.75);
    sv_phong_frame_ptr2->set_cd(transformed_wood_frame_ptr2);
    sv_phong_frame_ptr2->set_ks(0.1);
    sv_phong_frame_ptr2->set_exp(20.0);

//---------------------------------------------window material-----------------------------------

    // textured material:

    float exp_window = 100000.0; // 10000
    SV_GlossyReflector* sv_glossy_window_ptr = new SV_GlossyReflector;
    sv_glossy_window_ptr->set_samples(num_samples, exp_window);
    sv_glossy_window_ptr->set_ka(0.1);
    sv_glossy_window_ptr->set_kd(0.25);
    sv_glossy_window_ptr->set_ks(0.1);
    sv_glossy_window_ptr->set_exp(exp_window);
    sv_glossy_window_ptr->set_cd(new ConstantColor(RGBColor(0.5)));
    sv_glossy_window_ptr->set_kr(0.75);
    sv_glossy_window_ptr->set_exponent(exp_window);
    sv_glossy_window_ptr->set_cr(new ConstantColor(white));

接下来就是:
几何构建整个unit;
设置相应的材质和纹理。


    for (int ui=0; ui<unit_num; ui++) {
        double phi0_unit = angle_start + unit_angle_width * ui;
        double phi1_unit = angle_start + unit_angle_width * (ui+1);

        double phi0_wall1 = phi0_unit;
        double phi1_wall1 = phi0_wall1 + _wall_angle_width;

        BeveledWedge* wedge_wall_ptr1 = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_wall1 , phi1_wall1);
        wedge_wall_ptr1->set_material(sv_phong_wall_ptr1);
        add_object(wedge_wall_ptr1);


        double phi0_frame11 = phi1_wall1;
        double phi1_frame11 = phi1_wall1 + _frame_angle_width;

        BeveledWedge* wedge_frame11_ptr = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_frame11 , phi1_frame11);
        wedge_frame11_ptr->set_material(sv_phong_frame_ptr1);
        add_object(wedge_frame11_ptr);


        double phi0_frame21 = phi1_frame11;
        double phi1_frame21 = phi0_frame21 + _window_angle_width;

        BeveledWedge* wedge_frame21_ptr1 = new BeveledWedge(y20_unit, y21_unit, r10_unit, r11_unit, rb1_unit, phi0_frame21 , phi1_frame21);
        wedge_frame21_ptr1->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame21_ptr1);
        BeveledWedge* wedge_frame21_ptr2 = new BeveledWedge(y40_unit, y41_unit, r10_unit, r11_unit, rb1_unit, phi0_frame21 , phi1_frame21);
        wedge_frame21_ptr2->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame21_ptr2);
        BeveledWedge* wedge_frame21_ptr3 = new BeveledWedge(y60_unit, y61_unit, r10_unit, r11_unit, rb1_unit, phi0_frame21 , phi1_frame21);
        wedge_frame21_ptr3->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame21_ptr3);
        BeveledWedge* wedge_frame21_ptr4 = new BeveledWedge(y80_unit, y81_unit, r10_unit, r11_unit, rb1_unit, phi0_frame21 , phi1_frame21);
        wedge_frame21_ptr4->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame21_ptr4);

        BeveledWedge* wedge_window_ptr1 = new BeveledWedge(y30_unit, y31_unit, r20_unit, r21_unit, rb2_unit, phi0_frame21 , phi1_frame21);
        wedge_window_ptr1->set_material(sv_glossy_window_ptr);
        add_object(wedge_window_ptr1);
        BeveledWedge* wedge_window_ptr2 = new BeveledWedge(y50_unit, y51_unit, r20_unit, r21_unit, rb2_unit, phi0_frame21 , phi1_frame21);
        wedge_window_ptr2->set_material(sv_glossy_window_ptr);
        add_object(wedge_window_ptr2);
        BeveledWedge* wedge_window_ptr3 = new BeveledWedge(y70_unit, y71_unit, r20_unit, r21_unit, rb2_unit, phi0_frame21 , phi1_frame21);
        wedge_window_ptr3->set_material(sv_glossy_window_ptr);
        add_object(wedge_window_ptr3);


        double phi0_frame12 = phi1_frame21;
        double phi1_frame12 = phi0_frame12 + _frame_angle_width;

        BeveledWedge* wedge_frame12_ptr = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_frame12 , phi1_frame12);
        wedge_frame12_ptr->set_material(sv_phong_frame_ptr1);
        add_object(wedge_frame12_ptr);


        double phi0_frame22 = phi1_frame12;
        double phi1_frame22 = phi0_frame22 + _door_angle_width;

        BeveledWedge* wedge_frame22_ptr1 = new BeveledWedge(y20_unit, y21_unit, r10_unit, r11_unit, rb1_unit, phi0_frame22 , phi1_frame22);
        wedge_frame22_ptr1->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame22_ptr1);
        BeveledWedge* wedge_frame22_ptr2 = new BeveledWedge(y60_unit, y61_unit, r10_unit, r11_unit, rb1_unit, phi0_frame22 , phi1_frame22);
        wedge_frame22_ptr2->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame22_ptr2);
        BeveledWedge* wedge_frame22_ptr3 = new BeveledWedge(y80_unit, y81_unit, r10_unit, r11_unit, rb1_unit, phi0_frame22 , phi1_frame22);
        wedge_frame22_ptr3->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame22_ptr3);

        BeveledWedge* wedge_door_ptr1 = new BeveledWedge(y30_unit, y51_unit, r20_unit, r21_unit, rb2_unit, phi0_frame22 , phi1_frame22);
        wedge_door_ptr1->set_material(sv_glossy_window_ptr);
        add_object(wedge_door_ptr1);
        BeveledWedge* wedge_window2_ptr1 = new BeveledWedge(y70_unit, y71_unit, r20_unit, r21_unit, rb2_unit, phi0_frame22 , phi1_frame22);
        wedge_window2_ptr1->set_material(sv_glossy_window_ptr);
        add_object(wedge_window2_ptr1);


        double phi0_frame13 = phi1_frame22;
        double phi1_frame13 = phi0_frame13 + _gap_angle_width;
        BeveledWedge* wedge_frame13_ptr = new BeveledWedge(y60_unit, y81_unit, r10_unit, r11_unit, rb1_unit, phi0_frame13 , phi1_frame13);
        wedge_frame13_ptr->set_material(sv_phong_frame_ptr1);
        add_object(wedge_frame13_ptr);


        double phi0_frame23 = phi1_frame13;
        double phi1_frame23 = phi0_frame23 + _door_angle_width;

        BeveledWedge* wedge_frame23_ptr1 = new BeveledWedge(y20_unit, y21_unit, r10_unit, r11_unit, rb1_unit, phi0_frame23 , phi1_frame23);
        wedge_frame23_ptr1->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame23_ptr1);
        BeveledWedge* wedge_frame23_ptr2 = new BeveledWedge(y60_unit, y61_unit, r10_unit, r11_unit, rb1_unit, phi0_frame23 , phi1_frame23);
        wedge_frame23_ptr2->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame23_ptr2);
        BeveledWedge* wedge_frame23_ptr3 = new BeveledWedge(y80_unit, y81_unit, r10_unit, r11_unit, rb1_unit, phi0_frame23 , phi1_frame23);
        wedge_frame23_ptr3->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame23_ptr3);

        BeveledWedge* wedge_door_ptr2 = new BeveledWedge(y30_unit, y51_unit, r20_unit, r21_unit, rb2_unit, phi0_frame23 , phi1_frame23);
        wedge_door_ptr2->set_material(sv_glossy_window_ptr);
        add_object(wedge_door_ptr2);
        BeveledWedge* wedge_window3_ptr1 = new BeveledWedge(y70_unit, y71_unit, r20_unit, r21_unit, rb2_unit, phi0_frame23 , phi1_frame23);
        wedge_window3_ptr1->set_material(sv_glossy_window_ptr);
        add_object(wedge_window3_ptr1);


        double phi0_frame14 = phi1_frame23;
        double phi1_frame14 = phi0_frame14 + _frame_angle_width;

        BeveledWedge* wedge_frame14_ptr = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_frame14 , phi1_frame14);
        wedge_frame14_ptr->set_material(sv_phong_frame_ptr1);
        add_object(wedge_frame14_ptr);


        double phi0_frame24 = phi1_frame14;
        double phi1_frame24 = phi0_frame24 + _window_angle_width;

        BeveledWedge* wedge_frame24_ptr1 = new BeveledWedge(y20_unit, y21_unit, r10_unit, r11_unit, rb1_unit, phi0_frame24 , phi1_frame24);
        wedge_frame24_ptr1->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame24_ptr1);
        BeveledWedge* wedge_frame24_ptr2 = new BeveledWedge(y40_unit, y41_unit, r10_unit, r11_unit, rb1_unit, phi0_frame24 , phi1_frame24);
        wedge_frame24_ptr2->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame24_ptr2);
        BeveledWedge* wedge_frame24_ptr3 = new BeveledWedge(y60_unit, y61_unit, r10_unit, r11_unit, rb1_unit, phi0_frame24 , phi1_frame24);
        wedge_frame24_ptr3->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame24_ptr3);
        BeveledWedge* wedge_frame24_ptr4 = new BeveledWedge(y80_unit, y81_unit, r10_unit, r11_unit, rb1_unit, phi0_frame24 , phi1_frame24);
        wedge_frame24_ptr4->set_material(sv_phong_frame_ptr2);
        add_object(wedge_frame24_ptr4);

        BeveledWedge* wedge_window4_ptr1 = new BeveledWedge(y30_unit, y31_unit, r20_unit, r21_unit, rb2_unit, phi0_frame24 , phi1_frame24);
        wedge_window4_ptr1->set_material(sv_glossy_window_ptr);
        add_object(wedge_window4_ptr1);
        BeveledWedge* wedge_window4_ptr2 = new BeveledWedge(y50_unit, y51_unit, r20_unit, r21_unit, rb2_unit, phi0_frame24 , phi1_frame24);
        wedge_window4_ptr2->set_material(sv_glossy_window_ptr);
        add_object(wedge_window4_ptr2);
        BeveledWedge* wedge_window4_ptr3 = new BeveledWedge(y70_unit, y71_unit, r20_unit, r21_unit, rb2_unit, phi0_frame24 , phi1_frame24);
        wedge_window4_ptr3->set_material(sv_glossy_window_ptr);
        add_object(wedge_window4_ptr3);


        double phi0_frame15 = phi1_frame24;
        double phi1_frame15 = phi0_frame15 + _frame_angle_width;

        BeveledWedge* wedge_frame15_ptr = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_frame15 , phi1_frame15);
        wedge_frame15_ptr->set_material(sv_phong_frame_ptr1);
        add_object(wedge_frame15_ptr);


        double phi0_wall2 = phi1_frame15;
        double phi1_wall2 = phi1_unit;

        BeveledWedge* wedge_wall_ptr2 = new BeveledWedge(y10_unit, y11_unit, r10_unit, r11_unit, rb1_unit, phi0_wall2 , phi1_wall2);
        wedge_wall_ptr2->set_material(sv_phong_wall_ptr1);
        add_object(wedge_wall_ptr2);
    }

5,第五部分:台阶、房顶

这个可以理解问层级数为1的Rosette。

Phong材质,4号砂岩纹理。

创建台阶、房顶的相关代码如下:

////////////////////////////////////////steps and roof, Wedge///////////////////////////////////////

    double angle_start_s = 0;
    double angle_end_s = 360;
    int num_wedges = 9;
    double y0_s = - 0.1;
    double y1_s = 0.3;
    double rb_s = 0.025;
    double y0_r = 3.7;
    double y1_r = 4.1;
    double r0_s = 5.0;
    double r1_s = 7.0;

    for (int sj = 0; sj < num_wedges; sj++) {
        double angle_width = (angle_end_s - angle_start_s) / num_wedges;  // the azimuth angle extent of each wedge
        double phi0_s = angle_start_s + sj * angle_width;
        double phi1_s = phi0_s + angle_width;
        BeveledWedge* wedge_steps_ptr = new BeveledWedge(y0_s, y1_s, r0_s, r1_s, rb_s, phi0_s , phi1_s);
        BeveledWedge* wedge_roof_ptr = new BeveledWedge(y0_r, y1_r, r0_s, r1_s, rb_s, phi0_s , phi1_s);

        // noise:

        CubicNoise* noise_step_ptr = new CubicNoise;
        noise_step_ptr->set_num_octaves(6);
        noise_step_ptr->set_gain(2);            // not relevant when num_octaves = 1
        noise_step_ptr->set_lacunarity(0.5);     // not relevant when num_octaves = 1

        // ramp image:

        Image* image_step_ptr = new Image;
        image_step_ptr->read_ppm_file(".\\TextureFiles\\ppm\\sandstone_ramp4.ppm");

        // marble texture:

        FBmTextureRamp* sandstone_step_ptr = new FBmTextureRamp(image_step_ptr);
        sandstone_step_ptr->set_noise(noise_step_ptr);
        sandstone_step_ptr->set_perturbation(0.1);


        // transformed sandstone texture

        InstanceTexture* wedge_sandstone_step_ptr = new InstanceTexture(sandstone_step_ptr);
        set_rand_seed(20);
        wedge_sandstone_step_ptr->scale(0.25);
        wedge_sandstone_step_ptr->rotate_x(20.0 * (2.0 * rand_float() - 1.0));
        wedge_sandstone_step_ptr->rotate_y(30.0 * (2.0 * rand_float() - 1.0));
        wedge_sandstone_step_ptr->rotate_z(45.0 * (2.0 * rand_float() - 1.0));
        wedge_sandstone_step_ptr->translate(10.0 * (2.0 * rand_float() - 1.0), 20.0 * (2.0 * rand_float() - 1.0), 30.0 * (2.0 * rand_float() - 1.0));


        // material:

        SV_Phong* sv_phong_step_ptr = new SV_Phong;
        sv_phong_step_ptr->set_ka(0.25);
        sv_phong_step_ptr->set_kd(0.75);
        sv_phong_step_ptr->set_cd(wedge_sandstone_step_ptr);
        sv_phong_step_ptr->set_ks(0.1);
        sv_phong_step_ptr->set_exp(20.0);

        wedge_steps_ptr->set_material(sv_phong_step_ptr);
        add_object(wedge_steps_ptr);

        wedge_roof_ptr->set_material(sv_phong_step_ptr);
        add_object(wedge_roof_ptr);
    }

6,天空

凹半球面,Phong材质,图片映射

创建相关的代码:

////////////////////////////////////////sky, SpherePartConcave///////////////////////////////////////

    SpherePartConcave* spc_sky_ptr = new SpherePartConcave(Point3D(0, 0, 0), 1, 0, 360, 0, 90);

    // image:

    Image* image_sky_ptr = new Image;
//  image_sky_ptr->read_ppm_file(".\\TextureFiles\\ppm\\MorningSky.ppm");
    image_sky_ptr->read_ppm_file(".\\TextureFiles\\ppm\\EveningSky.ppm");

    // image based texture:

    ImageTexture* texture_image_sky_ptr = new ImageTexture;
    texture_image_sky_ptr->set_image(image_sky_ptr);

    InstanceTexture* it_image_sky_ptr = new InstanceTexture(texture_image_sky_ptr);
    it_image_sky_ptr->scale(1000000);

    // material:

    SV_Phong* sv_phong_sky_ptr = new SV_Phong;
    sv_phong_sky_ptr->set_ka(0.1);
    sv_phong_sky_ptr->set_kd(0.25);
    sv_phong_sky_ptr->set_cd(texture_image_sky_ptr);
    sv_phong_sky_ptr->set_ks(0.1);
    sv_phong_sky_ptr->set_exp(20.0);


    Instance* instance_spc_sky_ptr = new Instance(spc_sky_ptr);
    instance_spc_sky_ptr->scale(1000000);
    instance_spc_sky_ptr->rotate_x(-5);
//    instance_spc_sky_ptr->translate(0, -1000, 0);
    instance_spc_sky_ptr->set_material(sv_phong_sky_ptr);
    add_object(instance_spc_sky_ptr);

7,World::build()中的其他设置

    int num_samples = 16;
    int a = 1;

    vp.set_hres(1000/a);
    vp.set_vres(500/a);
    vp.set_samples(num_samples);

    tracer_ptr = new Whitted(this);

    Pinhole* pinhole_ptr = new Pinhole;
    pinhole_ptr->set_eye(0.0, 2.6, 6.8);
    pinhole_ptr->set_lookat(0.0, 0.0, -8);
    pinhole_ptr->set_view_distance(600/a);
    pinhole_ptr->compute_uvw();
    set_camera(pinhole_ptr);

    PointLight* point_light_ptr1 = new PointLight;
    point_light_ptr1->set_location(0, 3, -5);
    point_light_ptr1->scale_radiance(2.0);
    point_light_ptr1->set_cast_shadow(true);
    add_light(point_light_ptr1);

    PointLight* point_light_ptr2 = new PointLight;
    point_light_ptr2->set_location(0, 3, 5);
    point_light_ptr2->scale_radiance(2.0);
    point_light_ptr2->set_cast_shadow(true);
    add_light(point_light_ptr2);

8,测试图形

8.1 pinhole_ptr->set_view_distance(200/a);

分辨率1000*500,单像素点采样16次,耗时13898s。
这里写图片描述

8.2 pinhole_ptr->set_view_distance(400/a);

分辨率1000*500,单像素点采样16次,耗时12650s。
这里写图片描述

8.3 pinhole_ptr->set_view_distance(600/a);

分辨率1000*500,单像素点采样16次,耗时13778s。
这里写图片描述

8.4 pinhole_ptr->set_view_distance(800/a);

分辨率1000*500,单像素点采样16次,耗时12568s。
这里写图片描述

8.5 改变门的起始、终止角度

前面对应的角度都是:
double angle_start = 0;
double angle_end = 360;

现在将角度改为:
double angle_start = -90;
double angle_end = 270;
这里写图片描述
发现门的位置发生了旋转。其实对于柱子、台阶和房顶,都可以通过改变其对应的起始、终止角度来改变其在场景中所处的位置。

9,其他说明

完整代码下载链接:
http://download.csdn.net/detail/libing_zeng/9816036

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值