当前位置: 首页 > news >正文

正顺基碱基

之前的采样章节,开发了相对于z轴生成随机方向的方法,但是这个方法过于的片面,我们不能够保证所有的法线都与z轴对齐,我们需要考虑到不同的方向。

Relative Coordinates

标准正交基(ONB)是由三个相互正交的单位向量组成的集合。它是坐标系的一种严格子类型。笛卡尔 xyz 轴就是标准正交基的一个例子。我们所有的渲染结果,都是场景中物体的相对位置和方向投影到相机图像平面上得到的。相机和物体必须在同一坐标系中进行描述,这样投影到图像平面上的操作在逻辑上才是明确的,否则相机就没有确切的方法来正确渲染物体。要么必须在物体的坐标系中重新定义相机,要么必须在相机的坐标系中重新定义物体。最好一开始就让两者处于同一坐标系,这样就无需重新定义。只要相机和场景在同一坐标系中描述,一切就没问题。标准正交基定义了空间中距离和方向的表示方式,但仅有标准正交基是不够的。物体和相机需要通过它们相对于一个共同定义位置的位移来描述。这就是场景的原点 O,它代表了所有物体位移所参照的 “宇宙中心”。

例如我们有原点O以及标准的正交基x, y, z,若一个位置是(3,-2,7)则我们也可以表达为:

Location is O+3x−2y+7z

Generating an Orthonormal Basis(生成正交基)

这个过程概括的来讲就是我们有一个法线的方向向量。我们需要去定义一个a向量,然后通过叉积计算出垂直这两个向量的向量s,然后通过n和s的叉积得到另一个正交向量t。

a的定义不能与向量n平行

if (std::fabs(n.x()) > 0.9)
    a = vec3(0, 1, 0)
else
    a = vec3(1, 0, 0)

于是我们就可以写出这样的一个ONB类

ONB Class

#ifndef ONB_H
#define ONB_H

class ONB
{
public:
    ONB(const vec3& n)
    {
        axis[2] = unit_vector(n);
        vec3 a  = (std::fabs(axis[2].x()) > 0.9) ? vec3(0, 1, 0) : vec3(1, 0, 0);
        axis[1] = unit_vector(cross(axis[2], a));
        axis[0] = unit_vector(cross(axis[2], axis[1]));
    }

    const vec3& u() const { return axis[0]; }
    const vec3& v() const { return axis[1]; }
    const vec3& w() const { return axis[2]; }

    vec3 transform(const vec3& v) const 
    {
        return v.x() * axis[0] + v.y() * axis[1] + v.z() * axis[2];
    }
private:
    vec3 axis[3];
};

#endif

采样散射的光线

之前的在半球上进行余弦采样,采样的结果在靠近normal的部分概率会大一点,记得在vec的头文件中进行编辑

inline vec3 random_cosine_direction()
{
    vec3 ret;
    double r1 = random_double();
    double r2 = random_double();
    double z = std::sqrt(1.0 - r2);
    double phi = 2 * pi * r1;
    double x = std::cos(phi) * std::sqrt(r2);
    double y = std::sin(phi) * std::sqrt(r2);
    return vec3(x, y, z);
}
class lambertian : public material{
public:
    ...
    bool scatter(
        const Ray& r_in,const hit_record& rec,color& attenuation,Ray& scattered, double& pdf
    ) const override{
        ONB onb(rec.normal);
        vec3 direction = random_cosine_direction();
        direction = onb.transform(direction); // from local to world
        pdf = dot(onb.w(), direction) / pi;

        scattered = Ray(rec.p, direction, r_in.time());
        attenuation = tex->value(rec.u,rec.v,rec.p);
        return true;
    }
...
color ray_color(const Ray& r,int depth,const hittable& world) const{
    if(depth <= 0 ){
        return color(0,0,0);
    }
    hit_record rec;
    if(!world.hit(r,interval(0.001,infinity),rec)){ return background; }

    color attenuation;
    Ray scattered;
    double pdf_value;
    color color_from_emission = rec.mat->emitted(rec.u,rec.v,rec.p);
    if(!rec.mat->scatter(r,rec,attenuation,scattered, pdf_value)){
        return color_from_emission;
    }
    double scatter_pdf = rec.mat->scattering_pdf(r, rec, scattered);

    color color_from_scatter = (scatter_pdf * attenuation * ray_color(scattered,depth-1,world)) / pdf_value;
    return color_from_emission + color_from_scatter;
}

更新一下isotropic(各向同性) 材质

virtual double scattering_pdf(const Ray& r_in, const hit_record& rec, const Ray& scattered)
const override
{
    return 1.0 / (4 * pi);
}
virtual bool scatter(
const Ray& r_in,const hit_record& rec,color& attenuation,Ray& scattered, double& pdf
) const  override{
    scattered = Ray(rec.p,random_unit_vector(),r_in.time());
    attenuation = tex -> value(rec.u,rec.v,rec.p);
    pdf = 1.0 / (4 * pi);
    return true;
}

相关文章:

  • 【深度学习】环境和分布偏移
  • TCP/UDP协议与OSI七层模型的关系解析| HTTPS与HTTP安全性深度思考》
  • 【Mysql索引在什么情况下会失效?】
  • Kubernetes: Kustomize 进阶, 使用 Patch 精准操控 ConfigMap 多行文本,实现配置参数化
  • 笔记9——循环语句:for语句、while语句
  • PageHelper分页异常深度解析与解决方案
  • Maven 中的 Artifact 与 GroupId:定义与使用
  • 【愚公系列】《Python网络爬虫从入门到精通》019-使用 BeautifulSoup 的CSS选择器
  • deepseek本地调用
  • vscode的一些实用操作
  • CMake 编译工具
  • python基础语法
  • Spring Boot 与 Java 决策树:构建智能分类系统
  • 把程序加入开机自启动
  • 数据结构——单向循环链表、双链表、双向循环链表
  • Ubuntu 下 MySQL 安装与配置全攻略:从入门到精通
  • Zotero PDF Translate插件配置百度翻译api
  • 算法——前缀和
  • 采用 Ansys Workbench CFX 的 TwinMesh 应用
  • 分享一款AI绘画图片展示和分享的小程序
  • 科学家为AI模型设置“防火墙”,以防止被不法分子滥用
  • 国际锐评:菲律宾“狐假虎威”把戏害的是谁?
  • 夜读丨跷脚牛肉乐翘脚
  • 发布亮眼一季度报后,东阿阿胶股价跌停:现金流隐忧引发争议
  • 宜昌打造“算力之都”:产业链快速延伸,追逐千亿级产值
  • 五万吨级半潜船在沪完成装备装载