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

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

相关文章

将Java程序打包成EXE文件的实现方式

《将Java程序打包成EXE文件的实现方式》:本文主要介绍将Java程序打包成EXE文件的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录如何将Java程序编程打包成EXE文件1.准备Java程序2.生成JAR包3.选择并安装打包工具4.配置Launch4

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

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

SpringBoot实现微信小程序支付功能

《SpringBoot实现微信小程序支付功能》小程序支付功能已成为众多应用的核心需求之一,本文主要介绍了SpringBoot实现微信小程序支付功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录一、引言二、准备工作(一)微信支付商户平台配置(二)Spring Boot项目搭建(三)配置文件

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

如何用java对接微信小程序下单后的发货接口

《如何用java对接微信小程序下单后的发货接口》:本文主要介绍在微信小程序后台实现发货通知的步骤,包括获取Access_token、使用RestTemplate调用发货接口、处理AccessTok... 目录配置参数 调用代码获取Access_token调用发货的接口类注意点总结配置参数 首先需要获取Ac