《学一辈子光线追踪》 四点五 代码对比分析

2024-04-07 20:38

本文主要是介绍《学一辈子光线追踪》 四点五 代码对比分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

蒙特卡洛光线追踪技术系列 见 蒙特卡洛光线追踪技术

先粘贴一下以前的lambertian代码:

class lambertian :public material {
public:lambertian(texture*a):albedo(a){}virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered)const {vec3 target = rec.p + rec.normal + random_in_unit_sphere();scattered = ray(rec.p, target - rec.p);attenuation = albedo->value(rec.u,rec.v,rec.p);return true;}texture* albedo;
};vec3 color(const ray&r, hitable *world, int depth) {hit_record rec;if (world->hit(r, 0.001, MAXFLOAT, rec)) {ray scattered;vec3 attenuation;vec3 emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p);if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) {return emitted + attenuation*color(scattered, world, depth + 1);//}else {return emitted;}}else {return vec3(0, 0, 0);}
}

再放一下现在的代码:

class lambertian :public material {
public:lambertian(texture*a):albedo(a){}virtual float scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered)const {float cosine = dot(rec.normal, unitVector(scattered.direction()));if (cosine < 0)cosine = 0;return cosine / M_PI;}virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& alb, ray& scattered, float &pdf)const {/*vec3 direction;do {direction = random_in_unit_sphere();} while (dot(direction, rec.normal) < 0);scattered = ray(rec.p, unitVector(direction), r_in.time());alb = albedo->value(rec.u, rec.v, rec.p);pdf = 0.5 / M_PI;return true;*/vec3 target = rec.p + rec.normal + random_in_unit_sphere();scattered = ray(rec.p, unitVector(target - rec.p),r_in.time());alb = albedo->value(rec.u, rec.v, rec.p);pdf = dot(rec.normal, unitVector(scattered.direction())) / M_PI;return true;}texture* albedo;
};vec3 color(const ray&r, hitable *world, int depth) {hit_record rec;if (world->hit(r, 0.001, MAXFLOAT, rec)) {ray scattered;vec3 emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p);float pdf;vec3 albedo;if (depth < 50 && rec.mat_ptr->scatter(r, rec, albedo, scattered,pdf)) {return emitted + albedo * rec.mat_ptr->scattering_pdf(r,rec,scattered) *color(scattered, world, depth + 1);//}else {return emitted;}}else {return vec3(0, 0, 0);}
}

首先我想解决一个问题,为什么我的图片这么暗?

一开始我认为自己的代码是没有什么问题的,结果跟踪检查,发现原来是

return emitted + albedo* rec.mat_ptr->scattering_pdf(r,rec,scattered)  *color(scattered, world, depth + 1) / pdf;

最后面少了一个除以pdf。

这是我们p(direction) = cos(theta) / Pi的结果:

这是我们p(direction) = 1/(2*Pi)的结果

Color = (A * s(direction) * color(direction)) / p(direction)

对于lambertian 材料来说,散射pdf为 s(direction) = cos(theta) / Pi 。

为什么这两幅图我们分析应该产生的是一样的结果?(虽然最后结果不一样)

因为,我们两个图都是在发射出了不同pdf的光线后,又除以了各自的比重,所以都不会过采样也不会欠采样。

首先,对于朗伯材料来说,它的BRDF我们可以认为是固定的,即给定某根已经产生的scatter Ray,该Ray不管用什么pdf采样技术采样到的,计算scattering_pdf得到的值一定是一样的。

我们采用了某种技术来产生光线,我们假定该技术产生光线及其对应的PDF是正确的,所以当我们计算的帧数足够多了以后,按理来说是应该生成相同的图像才对。但是这里并没有生成相同的图像,有一个比较均匀,一个明暗对比比较明显。

这说明了一个问题:我们的生成随机方向的Ray并不符合我们理想中它的PDF,要么是产生半球方向的随机方向PDF不符,要么是产生朗伯随机方向的PDF不符,要么两者都不符。

 

这篇关于《学一辈子光线追踪》 四点五 代码对比分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/883616

相关文章

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python实现全能手机虚拟键盘的示例代码

《使用Python实现全能手机虚拟键盘的示例代码》在数字化办公时代,你是否遇到过这样的场景:会议室投影电脑突然键盘失灵、躺在沙发上想远程控制书房电脑、或者需要给长辈远程协助操作?今天我要分享的Pyth... 目录一、项目概述:不止于键盘的远程控制方案1.1 创新价值1.2 技术栈全景二、需求实现步骤一、需求

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

jupyter代码块没有运行图标的解决方案

《jupyter代码块没有运行图标的解决方案》:本文主要介绍jupyter代码块没有运行图标的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录jupyter代码块没有运行图标的解决1.找到Jupyter notebook的系统配置文件2.这时候一般会搜索到