《学一辈子光线追踪》 一 引言和一个简单的蒙特卡洛程序

2024-04-07 20:38

本文主要是介绍《学一辈子光线追踪》 一 引言和一个简单的蒙特卡洛程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

引言:

在一个周末的光线跟踪和光线跟踪:下周,你建立了一个“真正的”光线跟踪器。

在本卷中,我假设您将从事与光线跟踪相关的职业,我们将深入研究创建非常严肃的光线跟踪器的数学。完成后,您应该准备好开始处理电影和产品设计行业中许多重要的商业光线跟踪器。在这本小册子中,我没有介绍很多东西;我只探讨了编写Monte Carlo渲染程序的多种方法中的一种。我不做阴影光线(相反,我使光线更有可能朝向灯光)、双向方法bidirectional methods、Metropolis方法或光子贴图photon mapping。我所做的就是用研究这些方法的领域的语言来说话。我认为这本书可以是你以后工作的一个深入的接触,它将装备你的一些概念,数学和术语,你将需要学习其他知识。

一个简单的蒙特卡洛程序:

让我们从最简单的Monte Carlo(MC)程序开始。MC程序给出一个答案的统计估计,这个估计值随着运行时间的延长而变得越来越精确。简单程序产生噪音但得到更好的答案的这一基本特征就是MC的全部内容,它尤其适用于不需要高精度的图形等应用。

作为一个例子,我们来估计Pi。有很多方法可以做到这一点,Buffon针问题是一个典型的案例研究。我们将做一个受此启发的变化。假设你在一个正方形内有一个内接圆:

现在,假设你在正方形内随机选取点。那些最终进入圆内的随机点的分数应该与圆的面积成比例。确切的分数应该是圆面积与平方面积的比值。

Fraction = (Pi*R*R) / ((2R)*(2R)) = Pi/4
因为R被抵消了,我们可以选择任何计算上方便的R。让R=1以原点为中心:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "time.h"double myRandom() {return rand() / (RAND_MAX + 1.0);
}int main() {srand(time(NULL));int N = 1000;int inside_circle = 0;for (int i = 0;i < N;i++) {float x = 2 * myRandom() - 1;float y = 2 * myRandom() - 1;if (x*x + y*y < 1)inside_circle++;}printf("Estimate of PI = %f \n",4*float(inside_circle)/N);system("pause");
}

这给出了pi=3.196的答案估计值

如果我们将程序更改为永久运行并打印出运行估计,我们会得到很接近的估计。

我们很快接近圆周率,然后慢慢地接近它。这是收益递减定律的一个例子,其中每个样本的帮助小于上一个样本,这是MC最糟糕的部分。我们可以通过对样本进行分层(通常称为抖动)来缓解这种递减的回报,在这种情况下,我们不是随机抽取样本,而是在每个样本中抽取一个网格并抽取一个样本:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "time.h"
double myRandom() {return rand() / (RAND_MAX + 1.0);
}
int main() {srand(time(NULL));int inside_circle = 0;int inside_circle_stratified = 0;int sqrt_N = 10000;for (int i = 0;i < sqrt_N;i++) {for (int j = 0;j < sqrt_N;i++) {float x = 2 * myRandom() - 1;float y = 2 * myRandom() - 1;if (x*x + y*y < 1)inside_circle++;x = 2 * ((i + myRandom()) / sqrt_N) - 1;y = 2 * ((j + myRandom()) / sqrt_N) - 1;if (x*x + y*y < 1)inside_circle_stratified++;}}printf("Regular Estimate of PI = %f \n", 4 * float(inside_circle) / (sqrt_N*sqrt_N));printf("Stratified Estimate of PI = %f \n", 4 * float(inside_circle_stratified) / (sqrt_N*sqrt_N));system("pause");
}

得到结果:

有趣的是,分层方法不仅更好,而且收敛速度更快!不幸的是,这一优势随着问题的规模而减小(例如,对于3D球体体积版本,优势差距会更小)。这叫做维度诅咒。我们的MC光线追踪将是非常高的维度(每个反射增加两个维度),所以我不会在这本书分层。但是如果你曾经做过单次反射或阴影,或者一些严格的二维问题,你肯定想分层。

后记:

还记得我在这个系列中前几节关于《MCRT》书中讲到的关于分层方法 蒙特卡洛光线追踪 (准)蒙特卡洛积分,当时我在记录了一大堆数学公式以后,写了一个结论:

分层抽样的效果会比较好。

等我把下一节一维MC相关内容整理完以后,我再重新阐述一下MC分层抽样的原理。

这篇关于《学一辈子光线追踪》 一 引言和一个简单的蒙特卡洛程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

SpringBoot如何使用TraceId日志链路追踪

《SpringBoot如何使用TraceId日志链路追踪》文章介绍了如何使用TraceId进行日志链路追踪,通过在日志中添加TraceId关键字,可以将同一次业务调用链上的日志串起来,本文通过实例代码... 目录项目场景:实现步骤1、pom.XML 依赖2、整合logback,打印日志,logback-sp

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

四种简单方法 轻松进入电脑主板 BIOS 或 UEFI 固件设置

《四种简单方法轻松进入电脑主板BIOS或UEFI固件设置》设置BIOS/UEFI是计算机维护和管理中的一项重要任务,它允许用户配置计算机的启动选项、硬件设置和其他关键参数,该怎么进入呢?下面... 随着计算机技术的发展,大多数主流 PC 和笔记本已经从传统 BIOS 转向了 UEFI 固件。很多时候,我们也

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听