问题五十六:怎么用ray tracing画参数方程表示的曲面(3)—— b-spline surface

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

接“问题五十四”,已经简单学习了bezier曲线曲面,知道了双三次bezier曲面的矩阵表示形式,同时也以此画出了曲面图形。

这一章节主要以对比bezier曲线曲面和b-spline曲线曲面的方式来简单学习b-spline曲线曲面。

 



56.1 b-spline曲线








56.2 b-spline曲面










56.3 b-spline的C++代码实现

 

----------------------------------------------parametric_surface.h ------------------------------------------

parametric_surface.h

 

#ifndef PARAMETRIC_SURFACE_H
#define PARAMETRIC_SURFACE_H

#include <hitable.h>
#include "material.h"
#include "log.h"

#define TYPE 3
/*
TYPE=1: sphere;
TYPE=2: horn;
TYPE=3: bezier3;
*/
#define CURVE 1
/*
CURVE=1: bezier
CURVE=2: b-spline
*/

class parametric_surface : public hitable
{
    public:
        parametric_surface() {}
#if ((TYPE == 1) || (TYPE ==2))
        parametric_surface(vec3 cen, float a, float b, float c, float hy, material *m, float r, float t, float n) : center(cen), intercept_x(a), intercept_y(b), intercept_z(c), height_half_y(hy), ma(m), rho(r), theta(t), num(n) {}
#endif // TYPE
#if TYPE == 3
        parametric_surface(material *m, float r, float t, float n, vec3 *cp) : ma(m), rho(r), theta(t), num(n) {
/*相比bicubic Bezier surface,bicubic b-spline surface只需要改动如下黄底部分代码*/
            vec3 ctrl_points[4][4];
            for (int i=0; i<16; i++) {
                ctrl_points[(i/4)][(i%4)] = cp[i];
            }
#if CURVE == 1//bezier
            float matrix_t[4][4] = {{ 1,  0,  0, 0},
                                    {-3,  3,  0, 0},
                                    { 3, -6,  3, 0},
                                    {-1,  3, -3, 1}};
            float matrix[4][4] = {{1, -3,  3, -1},
                                  {0,  3, -6,  3},
                                  {0,  0,  3, -3},
                                  {0,  0,  0,  1}};
#endif // CURVE

#if CURVE == 2//b-spline

            float matrix_t_6[4][4] = {{ 1,  4,  1,0},

                                      {-3,  0,  3,0},

                                      { 3,-6,  3, 0},

                                      {-1,  3, -3, 1}};

            float matrix_t[4][4], matrix[4][4];

            for (int i=0; i<4; i++) {

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

                    matrix_t[i][j] =matrix_t_6[i][j] / 6.0;

                    matrix[j][i] = matrix_t[i][j];

                }

            }

#endif // CURVE

            float points_x[4][4], points_y[4][4], points_z[4][4], points_x_t[4][4], points_y_t[4][4], points_z_t[4][4];
            get_bezier_matrix_xyz_4_4(ctrl_points, points_x, points_y, points_z);
            matrix_4_4_multiply_4_4(matrix_t, points_x, points_x_t);
            matrix_4_4_multiply_4_4(points_x_t, matrix, matrix_c_x);
            matrix_4_4_multiply_4_4(matrix_t, points_y, points_y_t);
            matrix_4_4_multiply_4_4(points_y_t, matrix, matrix_c_y);
            matrix_4_4_multiply_4_4(matrix_t, points_z, points_z_t);
            matrix_4_4_multiply_4_4(points_z_t, matrix, matrix_c_z);
            float min_x = points_x[0][0];
            float max_x = points_x[0][0];
            float min_y = points_y[0][0];
            float max_y = points_y[0][0];
            float min_z = points_z[0][0];
            float max_z = points_z[0][0];
            for (int i=0; i<4; i++) {
                for (int j=0; j<4; j++) {
                    if (min_x > points_x[i][j]) {
                        min_x = points_x[i][j];
                    }
                    if (max_x < points_x[i][j]) {
                        max_x = points_x[i][j];
                    }
                    if (min_y > points_y[i][j]) {
                        min_y = points_y[i][j];
                    }
                    if (max_y < points_y[i][j]) {
                        max_y = points_y[i][j];
                    }
                    if (min_z > points_z[i][j]) {
                        min_z = points_z[i][j];
                    }
                    if (max_z < points_z[i][j]) {
                        max_z = points_z[i][j];
                    }
                }
            }
            bezier3_bl = vec3(min_x, min_y, min_z);
            bezier3_bh = vec3(max_x, max_y, max_z);
        }
#endif // TYPE
        virtual bool hit(const ray& r, float tmin, float tmax, hit_record& rec) const;
#if ((TYPE == 1) || (TYPE ==2))
        vec3 center;
        float intercept_x;
        float intercept_y;
        float intercept_z;
        float height_half_y;
#endif // TYPE
        material *ma;
        float rho, theta, num;
#if TYPE == 3
        float matrix_c_x[4][4], matrix_c_y[4][4], matrix_c_z[4][4];
        vec3 bezier3_bl, bezier3_bh;
#endif // TYPE
};

#endif // PARAMETRIC_SURFACE_H


----------------------------------------------main.cpp ------------------------------------------

main.cpp

/*这个文件bicubic Bezier surfacebicubic b-spline surface是完全一样的*/


//1
        vec3 ctrl_points[16] = {vec3(-3, 2,  0), vec3(-2, 3,  0), vec3(2, 3,  0), vec3(3, 2,  0),
                                  vec3(-3, 5, -2), vec3(-2, 5, -2), vec3(2, 5, -1), vec3(3, 5, -2),
                                  vec3(-3, 5, -4), vec3(-2, 5, -4), vec3(2, 5, -3), vec3(3, 5, -4),
                                  vec3(-3, 2, -6), vec3(-2, 3, -6), vec3(2, 3, -4), vec3(3, 2, -6)};
        hitable *list[1];
        list[0] = new parametric_surface(new lambertian(vec3(1.0, 0.0, 0.0)), 0.05, 20, 200);

        hitable *world = new hitable_list(list,1);

        vec3 lookfrom(10, 10, 10);
        vec3 lookat(0, 3, -2);
        float dist_to_focus = (lookfrom - lookat).length();
        float aperture = 0.0;
        camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture, 0.7*dist_to_focus);


 

输出图片bicubic Bezier surface(前),bicubic b-spline surface(后)对比:

 

#if TYPE == 3

        #define UN 16

        #define VN 16

#endif // TYPE

 

//1

       vec3 ctrl_points[4][4] = {vec3(-3, 2,  0), vec3(-2, 3,  0), vec3(2, 3,  0), vec3(3, 2,  0)},

                                      {vec3(-3,5, -2), vec3(-2, 5, -2), vec3(2, 5, -1), vec3(3, 5, -2)},

                                      {vec3(-3,5, -4), vec3(-2, 5, -4), vec3(2, 5, -3), vec3(3, 5, -4)},

                                      {vec3(-3,2, -6), vec3(-2, 3, -6), vec3(2, 3, -4), vec3(3, 2, -6)};


 

//2

        vec3 ctrl_points[16] = {vec3(-3, 2,  0), vec3(-2, 3,  0), vec3(2, 3,  0), vec3(3, 2,  0)},

                                      {vec3(-3,5, -2), vec3(-2, 5, -2), vec3(2, 4, -1), vec3(3,3, -2)},

                                      {vec3(-3,5, -4), vec3(-2, 5, -4), vec3(2, 4, -3), vec3(3,3, -4)},

                                      {vec3(-3,2, -6), vec3(-2, 3, -6), vec3(2, 3, -4), vec3(3, 2, -6)};


 

//3

        vec3 ctrl_points[16] = {vec3(-3,2,  0), vec3(-2, 3,  0), vec3(2, 3,  0), vec3(3, 2,  0)},

                                      {vec3(-3,5, -2), vec3(-2, 5, -2), vec3(2, 2, -1), vec3(3,1, -2)},

                                      {vec3(-3,5, -4), vec3(-2, 5, -4), vec3(2, 2, -3), vec3(3,1, -4)},

                                      {vec3(-3,2, -6), vec3(-2, 3, -6), vec3(2, 3, -4), vec3(3, 2, -6)};

  

//4

        vec3ctrl_points[16] = {vec3(-3, 2,  0),vec3(-2, 3,  0), vec3(2, 5,  0), vec3(3, 5,  0)},

                                      {vec3(-3,5, -2), vec3(-2, 5, -2), vec3(2, 2, -1), vec3(3, 1, -2)},

                                      {vec3(-3,5, -4), vec3(-2, 5, -4), vec3(2, 2, -3), vec3(3, 1, -4)},

                                      {vec3(-3,2, -6), vec3(-2, 3, -6), vec3(2, 5, -4), vec3(3,5, -6)};

 

//5

        vec3 ctrl_points[16] = {vec3(-3, 2,  0), vec3(-2, 3,  0), vec3(2, 5,  0), vec3(3, 5,  0)},

                                      {vec3(-3,5, -2), vec3(-2, 5, -2), vec3(2, 0, -1), vec3(3, -1, -2)},

                                      {vec3(-3,5, -4), vec3(-2, 5, -4), vec3(2, 0, -3), vec3(3,-1, -4)},

                                      {vec3(-3,2, -6), vec3(-2, 3, -6), vec3(2, 5, -4), vec3(3, 5, -6)};

 

//11

        vec3 ctrl_points[16] = {vec3(-3,2,  0), vec3(-2, 3,  0), vec3(2, 5,  0), vec3(-6, 3,  0),

                                     vec3(-3, -1,-2), vec3(-2, 5, -2), vec3(2, 0, -1), vec3(-63, -2),

                                     vec3(-3, -1,-4), vec3(-2, 5, -4), vec3(2, 0, -3), vec3(-63, -4),

                                      vec3(-3, 2, -6), vec3(-2, 3, -6), vec3(2,5, -4), vec3(-6,  3, -6)};


 






  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用chrome://tracing/工具,你可以按照以下步骤进行操作: 1. 在Chrome浏览器的地址栏中输入chrome://tracing/并按下回车键,即可打开Tracing工具。\[1\] 2. 在Tracing工具中,点击"Load"按钮,选择你的JSON文件并加载它。\[1\] 3. 加载完成后,你将能够在Tracing工具中查看波形图和其他相关信息。\[1\] 请注意,JSON文件的格式需要符合Chrome能够识别的格式。你可以参考提供的示例JSON文件\[2\]来确保你的文件格式正确。另外,值得注意的是,Chrome的Tracing工具默认使用微秒作为时间戳的单位,所以在使用工具时,你可能需要将时间戳转换为正确的格式。\[3\] #### 引用[.reference_title] - *1* [chrome://tracing 性能分析神器](https://blog.csdn.net/zgcjaxj/article/details/115077815)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [关于BenchMark/c++11计时器/Chrome:tracing 问题](https://blog.csdn.net/jingdianjiuchan/article/details/124529270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值