[Ray Tracing in One Weekend] 笔记

前言

本文参照自raytracing in one weekend教程,地址为:https://raytracing.github.io/books/RayTracingInOneWeekend.html

什么是光线追踪?

光线追踪模拟现实中的成像原理,通过模拟一条条直线在场景内反射折射,最终获知物体表面的颜色。现实世界中,光线最终射向相机,获得成像,光线追踪则是从相机出发,向场景中反向发射光线,从而推出相机“底片”中每个像素的颜色。

现实中的相机很发杂,包括多组透镜,在成像时不是光线直接射入相机,需要经过多次折射。我们这里的光线追踪更类似于在模拟小孔成像(只不过小孔成像获得的图像是反置的,我们直接得到正向的结果,相当于对反置图像做了反置),我们在小孔的位置放置相机。

在这里插入图片描述

光线追踪和光栅化是两种不同的渲染方式,光栅化相当于把物体表面直接反射或发射的颜色返回给相机“底片”,场景中的各种阴影、遮蔽等效果都是通过预计算等方法得出的,而光线追踪会考虑物体表面光线多次反射或折射的结果,直接可以得到场景中的阴影、遮蔽等细节效果。

在具体实现的过程中,我们会在相机的正前方设置一个虚拟画布,相当于相机的底片(正常来说相机底片应当是在相机背面的,不过为了直观以及便于确定每条光线的方向,直接在相机前方设置),虚拟画布上每个位置的颜色代表了最终渲染结果对应像素的颜色。在发射光线时,通常以相机为起点,虚拟画布上的每个位置为终点,构建一条射线,每个方向可以根据采样设置发射多条射线。每个方向的射线的平均结果为对应像素的最终颜色。

在这里插入图片描述

光栅器的构建过程

这一部分是我在学习raytracing in one weekend教程时,我认为重点部分的罗列。

图像格式

raytracing in one weekend教程中采用了ppm格式,这种格式很简单,可以用ASCII文本表示。详细介绍可以参考:https://zhuanlan.zhihu.com/p/609960339

基本的光追过程

简述一下光线追踪的过程:

  1. 屏幕上的每一个像素都进行光线投射。

  2. 光线的每次投射都需要判断交点,而且投射到交点后还可能产生反射、折射,那么就往相应的方向继续进行新的投射,直到投射到天空或者投射次数达到限制。

  3. 最后,将每个交点的受光照情况以一定权重综合起来,得到一束光线获得的颜色,根据采样次数,每个像素发出的多个颜色的平均值为该像素的颜色。

下图是一个示例。

在这里插入图片描述

光线追踪的伪代码:

RayTracing(Ray ray, hittable_list world, int depth){
    if(depth <= 0)
        return black color;
    
    hit_record rec; // 弹射点的属性记录
    
    if(Intersect(ray, world, out rec)){
        material = rec.mat; // 弹射点所在物体的材质
        normal = rec.normal;
        
        localColor = ShaderCalculate(ray, material, normal);
        out_ray = Get_outputRay(ray, material, normal);

        localColor = shaderCalculate(direction,hitpoint,normal);
        return localColor * RayTracing(out_ray, world, depth - 1);
    }
    else{
        return the color of background;
    }
}

抗锯齿

看到一个有趣的真相:每个小像素块不是正方形,参考文献,不过为了简单起见,我们假设每个小像素块是正方形。

这里为了进行抗锯齿,采用了一定程度的随机,即从相机向虚拟画布发射光线时,以像素为单位为射线的终点做随机扰动。

在代码中的体现如下:

ray get_ray(int i, int j) const {
        // 获取位置 i,j 处像素的随机采样光线。

        auto pixel_center = pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v);
        auto pixel_sample = pixel_center + pixel_sample_square();

        auto ray_origin = center;
        auto ray_direction = pixel_sample - ray_origin;

        return ray(ray_origin, ray_direction);
    }

    vec3 pixel_sample_square() const {
        // 返回一个单位像素正方形周围的随机点。
        
        auto px = -0.5 + random_double();
        auto py = -0.5 + random_double();
        return (px * pixel_delta_u) + (py * pixel_delta_v);
    }

漫反射材质

(最简单的)漫反射材质,在光线射入表面后,会在法线半球随机射出。

而如何获得一个随机的单位球内的向量?文中给出的方法是在单位正方体内随机取点,将不在单位球内的点丢弃。而进一步删选是否在表面法线半球,则可以通过将获得的向量与法线点积,如果点积结果为正则采用,为负则丢弃。

为了让漫反射结果更真实,我们应该采用Lambertian Reflection。采用这种方法,在采样时越靠近法线处概率越高。我们可以在与表面交点相切的球体内采样反射光线,示意图如下:

在这里插入图片描述

gamma矫正

另外需要注意gamma矫正,简单来说,屏幕是处于gamma空间上的,而我们渲染的结果在未经处理时是在linear空间上的,为了使色彩不失真,我们需要将渲染的结果转换到gamma空间上。

以下是gamma矫正前和gamma矫正后的对比图:

在这里插入图片描述

金属材质

这里的金属材质与镜子比较类似,金属材质有一个fuzz参数,代表材质表面反射的模糊度。当反射模糊度为零时,这个材质就相当于一个带颜色的镜子。

fuzz参数:反射时,可以对反射光线加一个随机,表示模糊效果。具体随机方式如下图,对反射光线的末端,加一个半径为fuzz范围的球体随机。

在这里插入图片描述

金属材质的效果:

在这里插入图片描述

玻璃材质

引入了光线的折射,下面贴一下教程原文的计算表示过程。

在这里插入图片描述

在做折射时,需要注意全反射的情况。

另外,在现实生活中,当我们贴近玻璃表面时,玻璃会表现地像镜子,这个效果可以用Christophe Schlick给出的公式来模拟。
在代码中,当F大于给定的值时,我们认为此时为反射。
F ( F 0 , θ i ) = F 0 + ( 1 − F 0 ) ( 1 − c o s θ i ) 5 F 0 = ( η 1 − η 2 η 1 + η 2 ) 2 = ( η − 1 η + 1 ) 2 F(F_0,\theta_i) = F_0 + (1 - F_0)(1 - cos\theta_i)^5 \\ F_0 = (\frac{\eta_1 - \eta_2}{\eta_1 + \eta_2})^2 = (\frac{\eta - 1}{\eta + 1})^2 F(F0,θi)=F0+(1F0)(1cosθi)5F0=(η1+η2η1η2)2=(η+1η1)2

此时我们得到的是一个通过物体后光线颠倒的效果,这显然不真实。

在这里插入图片描述

有一个trick,我们可以镶嵌两层玻璃球(内层的玻璃球采用负半径,让表面法线颠倒),消除之前的颠倒效果。

在这里插入图片描述

散焦模糊(defocus blur)

这个概念是模仿相机的景深,指的是在相机拍摄时,焦距附近的图像会很清晰,而焦距之外的图像比较模糊。

要模仿真实的相机,我们还需要模拟相机内各种透镜的折射,这太复杂了。为了简单一点,教程中把我们的相机从发射点扩展为发射圆盘,即每次发射光线时从一个半径为r的圆盘中发射光线,穿过虚拟画布。这种模拟不是严格的相机成像,但是效果还不错,具体原理我没怎么搞清。渲染出来的结果如下图:

在这里插入图片描述

最终的渲染结果

最终作者给了一个大场景,我在机器上跑了十多个小时才跑出来。

在这里插入图片描述

完整代码

不想上传个单独的github项目了,就传在网盘上吧:

链接:https://pan.baidu.com/s/1TQUo7GbRUsR-tyLDOv_vOg?pwd=duxm
提取码:duxm
–来自百度网盘超级会员V6的分享

ps: 我只分享了源代码,没有什么依赖库,应该可以直接跑出图片。

参考

https://raytracing.github.io/books/RayTracingInOneWeekend.html

https://zhuanlan.zhihu.com/p/168791125

https://zhuanlan.zhihu.com/p/357142662

https://www.cnblogs.com/KillerAery/p/15106773.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/254492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tinymce 5 插入代码集成highlight.js(踩坑记录)

目录 官方教程 坑点一 坑点二 坑点三 坑点四 TinyMCE HighLight.js Plugin 官方教程 1. 引入 tinymce 库文件 <script src"tinymce.min.js"></script> 2. 引入 highlight js 库文件 <script src"plugins/becodesample/highlight.js-11.…

word怎么分页?学会这几招,轻松掌握分页功能!

Microsoft Word作为办公文档处理的主力工具&#xff0c;其强大的排版功能为用户提供了丰富的文档编辑体验。其中&#xff0c;分页是一个常用但可能被忽视的重要功能&#xff0c;能够使文档结构更清晰、更易读。本文将向您介绍word怎么分页的三种方法&#xff0c;帮助您更好地掌…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Text文本组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之文本组件 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、文本组件 Text 是显示文本的基础组件之一&#xff0c;它可以包含子组件 Span &…

软件测试面试八股文(超详细整理)

请你说一说测试用例的边界 参考回答&#xff1a; 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充&#xff0c;这种情况下&#xff0c;其测试用例来自等价类的边界。 常见的边界值 1)对16-bit 的整数而言 32…

ArkTS-一次开发,多端部署

展示 官方代码适配解读 官方代码&#xff1a;一次开发&#xff0c;多端部署-视频应用 解读 适配多端&#xff1a;根据屏幕大小来判断不同客户端&#xff0c;BreakpointSystem.ets中引入官方API获取 ohos.mediaqueryCommonConstants.ets定义好不同屏幕范围大小&#xff0c;供需…

反爬虫介绍及其处理方法

反爬虫机制 封IP&#xff1a;监控短时间内同一地址的请求次数过大登录及验证码&#xff1a;对于监控后封IP之后短时间内继续的大量请求&#xff0c;要求登陆或验证码通过验证之后才能继续进行。健全账号体制&#xff1a;即核心数据只能通过账号登录后才能进行访问。动态加载数…

Xpath注入

这里学习一下xpath注入 xpath其实是前端匹配树的内容 爬虫用的挺多的 XPATH注入学习 - 先知社区 查询简单xpath注入 index.php <?php if(file_exists(t3stt3st.xml)) { $xml simplexml_load_file(t3stt3st.xml); $user$_GET[user]; $query"user/username[name&q…

ubuntu 开机提示 you are in emergency mode,journalctl -xb

进入系统界面 回车输入&#xff1a; journalctl -xb -p3 查看出问题的盘符类型。 然后 lsblk 查看挂载情况 我的是/dev/sda3没有挂载上&#xff0c;对应/home目录&#xff0c;注意这时候不要直接mount 需要先修复 fsck -y /dev/sda3等待修复完成&#xff0c;在重新挂载 moun…

【网络安全技术】传输层安全——SSL/TLS

一、TLS位置及架构 TLS建立在传输层TCP/UDP之上&#xff0c;应用层之下。 所以这可以解决一个问题&#xff0c;那就是为什么抓不到HTTP和SMTP包&#xff0c;因为这两个在TLS之上&#xff0c;消息封上应用层的头&#xff0c;下到TLS层&#xff0c;TLS层对上层消息整个做了加密&…

Bert-vits2-v2.2新版本本地训练推理整合包(原神八重神子英文模型miko)

近日&#xff0c;Bert-vits2-v2.2如约更新&#xff0c;该新版本v2.2主要把Emotion 模型换用CLAP多模态模型&#xff0c;推理支持输入text prompt提示词和audio prompt提示语音来进行引导风格化合成&#xff0c;让推理音色更具情感特色&#xff0c;并且推出了新的预处理webuI&am…

GPT-4.5!!!

GPT-4 还没用明白&#xff0c;GPT-4.5 就要发布了。 最近&#xff0c;OpenAI 泄露了 GPT-4.5 的发布页面&#xff0c;除了进一步增强复杂推理和跨模态理解&#xff0c;GPT-4.5 增加了一个更加强大的功能——3D。 3D 功能的进一步支持&#xff0c;也就意味着多模态最后一块版图…

Linux部署Nacos注册中心结合内网穿透实现远程访问UI管理界面

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik8. 结语 Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a…

Keil的配置向导

配置向导 配置向导是一个集成的编辑器实用程序&#xff0c;用于在汇编、C/ c或初始化文件中生成类似gui的配置控件。使用源代码中的配置向导注释来生成控件。 官方例子 名称含义 Option 是设备属性&#xff0c;可以用树状结构表示。每个项目都可以有一个解释性的工具提示。V…

阿里云|人工智能(AI)技术解决方案

函数计算部署Stable Diffusion AI绘画技术解决方案 通过函数计算快速部署Stable Diffusion模型为用户提供快速通过文字生成图片的能力。该方案通过函数计算快速搭建了AIGC的能力&#xff0c;无需管理服务器等基础设施&#xff0c;专注模型的能力即可。该方案具有高效免运维、弹…

Ubuntu安装ARM交叉编译器

Ubuntu安装交叉编译器 更新apt # 更新apt sudo apt update安装gcc sudo apt install build-essential查看gcc版本 gcc -v下载交叉编译工具 复制到用户目录 解压 tar -xvf gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabihf.tar.xz移动到/opt/下 sudo ./gcc-linaro-5.…

天猫数据平台-淘宝天猫数据-天猫销售数据分析:11月天猫平台滑雪运动装备行业销量翻倍!

随着天气变冷、冬季来临&#xff0c;迎来了疫情后的首个滑雪季&#xff0c;加之自冬奥会结束以来&#xff0c;大众参与冰雪运动的热度持续攀升&#xff0c;因此&#xff0c;冰雪运动的需求正集中释放。 根据相关数据显示&#xff0c;11月以来&#xff0c;全国滑雪场门票预订量较…

Leetcode—746.使用最小花费爬楼梯【简单】

2023每日刷题&#xff08;六十一&#xff09; Leetcode—746.使用最小花费爬楼梯 算法思想 参考灵神 实现代码 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {int n cost.size();vector<int> f(n 1);for(int i 2; i < n;…

C# WPF上位机开发(ExtendedWPFToolkit扩展包使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 虽然个人人为当前的c# wpf内容已经足够多&#xff0c;但是肯定还是有很多个性化的需求没有满足。比如说不够好看&#xff0c;比如说动画效果不好&a…

从人的安全价值观看企业的安全发展

文章目录 每日一句正能量前言感受之一&#xff0c;安全价值观是体现个人人生价值的最高境界&#xff0c;是人与企业和谐发展的基本保障&#xff0c;也是企业安全发展的理论导向。感受之二&#xff0c;安全价值观是企业承担社会责任的主要表现&#xff0c;是体现企业价值的根基&…

app上架-您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(相机)等权限,不符合华为应用市场审核标准。

上架提示 您的应用在运行时&#xff0c;未同步告知权限申请的使用目的&#xff0c;向用户索取&#xff08;相机&#xff09;等权限&#xff0c;不符合华为应用市场审核标准。 测试步骤&#xff1a;管理-添加-点击二维码&#xff0c;申请相机权限 修改建议&#xff1a;APP在调…