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

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

相关文章

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

宝塔面板部署青龙面板教程【简单易上手】

首先,你得有一台部署了宝塔面板的服务器(自己用本地电脑也可以)。 宝塔面板部署自行百度一下,很简单,这里就不走流程了,官网版本就可以,无需开心版。 首先,打开宝塔面板的软件商店,找到下图这个软件(Docker管理器)安装,青龙面板还是安装在docker里,这里依赖宝塔面板安装和管理docker。 安装完成后,进入SSH终端管理,输入代码安装青龙面板。ssh可以直接宝塔里操作,也可以安装ssh连接

美容美发店营销版微信小程序源码

打造线上生意新篇章 一、引言:微信小程序,开启美容美发行业新纪元 在数字化时代,微信小程序以其便捷、高效的特点,成为了美容美发行业营销的新宠。本文将带您深入了解美容美发营销微信小程序,探讨其独特优势及如何助力商家实现业务增长。 二、微信小程序:美容美发行业的得力助手 拓宽客源渠道:微信小程序基于微信社交平台,轻松实现线上线下融合,帮助商家快速吸引潜在客户,拓宽客源渠道。 提升用户体验:

程序人生--拔丝地瓜

一个会享受生活的人,难免会执迷于探索“三餐茶饭,四季衣裳”的朴素涵义。如今在这繁杂喧闹、竞争激烈的社会环境里,如何才能从周而复始的生活中挖掘出一点儿期待!这是一个仁者见仁智者见智的开放性话题。对于大部分的人来说,看电影、运动、旅游、美食、加班....是假日的备选安排。 春节临走之前,再次尝试“拔丝地瓜”,为何要强调“再次”二字?因为这道甜菜我已经尝试过很多次,失败与成功都经历过。十几年的烧饭经历