光线追踪(RayTracing)算法

2023-11-07

1、Forward Tracing

假设有一个每次只发射一个光子的光源,光子从光源发出并沿着直线路径行进,直至撞击到物体表面,忽略光子的吸收,该光子会以随机的方向反射。如果光子撞击到我们的眼睛表面,则我们会看到光子被反射的点。

现在从计算机图形的角度来看待这种情况。首先,我们用像素组成的平面代替我们的眼睛。在这种情况下,发射的光子将撞击图形平面上许多像素的一个,并将该点的亮度增加到大于零的值。重复多次直到所有的像素被调整,创建一个计算机生成的图像。这种技术称为前向光线追踪(Forward Tracing),因为我们是沿着光子从光源向观察者的前进的路径。

这种技术在计算机中模拟光子与物体相互作用是不太现实的,因为在实际中反射的光子击中眼睛表面的可能性是非常非常低的,我们必须投射大量的光子才能找到一个能够引起眼睛注意的。此外,我们也不能保证物体的表面被光子完全覆盖,这是这项技术的主要缺点。

2、Backward Tracing

并追踪从眼睛进入到场景中的光线。光线照到一个物体时,我们可以通过将另一条光线(称为光线或阴影光线)从击中点投射到场景的光线,得到它所接受到的光子数量。这个“光线”有的时候会被另一个物体阻挡,这意味着我们原来的撞击点在阴影中,没有获得任何照明。

3.算法实现

(1)光线追踪算法采用由像素组成的图像。对于图像中的每个像素,它将主光线投射到场景中。该主光线的方向是通过追踪从眼睛到像素中心线获得的。一旦我们确定了主射线的方向,我们就开始检查场景中的每个对象,看它是否与其中的任何一个相交。当发生主射线与多个对象相交的情况时,我们选择交点离眼睛最近的物体。

(2)我们从交叉点向光源投射阴影射线。如果这条特定的光线在通往光源的路上不与某个物体相交,那么这个点就被照亮了。

(3)如果它与另一个物体相交,则该物体在其上投下阴影。

(4)如果我们对每个像素重复这一操作,就可以获得三维场景的二维表示。

4.伪代码

for (int j = 0; j < imageHeight; ++j) { 
    for (int i = 0; i < imageWidth; ++i) { 
        // compute primary ray direction
        Ray primRay; 
        computePrimRay(i, j, &primRay); 
        // shoot prim ray in the scene and search for intersection
        Normal nHit; 
        float minDist = INFINITY; 
        Object object = NULL; 
        for (int k = 0; k < objects.size(); ++k) { 
            if (Intersect(objects[k], primRay, &pHit, &nHit)) { 
                float distance = Distance(eyePosition, pHit); 
                if (distance < minDistance) { 
                    object = objects[k]; 
                    minDistance = distance; // update min distance 
                } 
            } 
        } 
        if (object != NULL) { 
            // compute illumination
            Ray shadowRay; 
            shadowRay.direction = lightPosition - pHit; 
            bool isShadow = false; 
            for (int k = 0; k < objects.size(); ++k) { 
                if (Intersect(objects[k], shadowRay)) { 
                    isInShadow = true; 
                    break; 
                } 
            } 
        } 
        if (!isInShadow) 
            pixels[i][j] = object->color * light.brightness; 
        else 
            pixels[i][j] = 0; 
    } 
} 

 5.加入反射和折射

在光学中,反射和折射是总所周知的现象。反射和折射分向都是基于相交点处的法线和入射光线(主光线)的方向。为了计算折射方向,我们还需指定材料的折射率。

加入反射折射后,进行以下三个步骤:

(1)计算反射:我们需要交点处的法线和主光线的方向。一旦我们获得了反射方向,我们就朝这个方向发射新的光线。我们假设反射光线撞击了红色球体,通过向光线投射阴影射线来找出到达红色球体上的那个点的光线多少。这会得到一种颜色(如果是阴影,则为黑色),然后乘以光强并返回到玻璃球的表面。

(2)计算折射:我们需要在知道击中点的法线,主射线方向和材料的折射率。当光线进入并离开玻璃物体时,光线的方向会改变。当折射的光线离开玻璃球时,它会碰到一个绿色的球体。在那里,我们再次计算绿色球体和折射射线之间交点处的局部照明(通过拍摄阴影射线)。然后,将颜色(如果被遮挡,则为黑色)乘以光强并返回到玻璃球的表面。

(3)应用菲涅尔方程:我们需要玻璃球的折射率,主光线的角度,以及击中点的法线。使用点积,菲涅耳方程返回两个混合值。

这种算法的美妙之处在于它是递归的。迄今为止,在我们研究过的情况下,反射光线照射到一个红色的、不透明的球体上,而折射光线照射到一个绿色的、不透明的和漫射的球体上。但是,我们会想象红色和绿色的球体也是玻璃球。为了找到由反射和折射光线返回的颜色,我们必须按照与原始玻璃球一起使用的红色和绿色球体的相同过程。这是光线追踪算法的一个严重缺陷。想象一下,我们的相机是在一个只有反射面的盒子里。从理论上讲,光线被困住了,并且会持续不断地从箱子的墙壁反弹(或者直到你停止模拟)。出于这个原因,我们必须设置一个任意的限制值,从而防止光线相互作用导致的无限递归。每当光线反射或折射时,其深度都会增加。当光线深度大于最大递归深度时,我们就停止递归过程。

伪代码

// compute reflection color
color reflectionCol = computeReflectionColor(); 
// compute refraction color
color refractionCol = computeRefractionColor(); 
float Kr; // reflection mix value 
float Kt; // refraction mix value 
fresnel(refractiveIndex, normalHit, primaryRayDirection, &Kr, &Kt); 
// mix the two
color glassBallColorAtHit = Kr * reflectionColor + (1-Kr) * refractionColor; 

转自:https://blog.csdn.net/hmbxsy/article/details/80509876

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

光线追踪(RayTracing)算法 的相关文章

  • 10分钟迅速回顾机器人运动学方向分析

    首先我们要清晰我们的目标 我们研究机械手臂的方向要干啥 无非两点 知道每个关节如何旋转移动的情况下 手臂末端会移动到哪里 即正向运动学 想要让手臂移动到某个地方 该如何控制每个关节 同时 分析机器人机械手臂运动的核心就是 转移矩阵 tran
  • RSA用私钥加密。。

    RSA是一种使用非对称加密的算法 以前总认为只有公钥加密 私钥解密的 现在看到了一篇关于私钥加密 公钥解密的文章 怀疑人生 现把代码贴在下面 正确的方式是公钥加密 私钥解密 私钥加签 公钥验签 加密是为了防止信息被泄露 而签名是为了防止信息
  • Android 检测是否安装微信、支付宝

    检测设备上是否安装微信 支付宝的代码 检测是否安装支付宝 param context return public static boolean isAliPayInstalled Context context Uri uri Uri pa
  • 在vue3中配置ByteMD掘金同款markdown编辑器

    最近因为想要一个富文本编辑器集合到项目中 在查找网上很多资料后 选择了ByteMD 编辑器 ByteMD 编辑器是字节跳动的掘金团队所开源的一个编辑器组件 还挺好用的 那如果要在vue3项目中配置ByteMD编辑器要如何配置呢 用一个小de
  • 如何在SDK中打开例程

    第一步 在某个硬盘如D盘中新建一个文件夹 名字随意取 如为 10 2 xinlicheng 第二步 打开CCS 设置工作路径为10 2 xinlicheng的工作路径 并点launch 如下图 第三步 在菜单栏中的project 下拉找到i
  • 微服务实战中如何理解服务熔断和降级的区别

    你好 我是老王 不做隔壁的邻居 只想交个朋友 欢迎关注我的公众号 王自简 以下内容若引起您的不适 欢迎指正 您的批评是我成长的动力 熔断 举个例子解释 生活中每家每户都在用电 小明家的电线因为故障导致了小明家停电了 而小李 小张家的电是正常
  • QTableWidget部件使用

    一 部件说明 qtablewidget部件常用来作为qt界面表格显示工具 qtablewidget是qtableview的子类 其区别是qtableview可以使用自定义的数据模型来显示内容 而qtablewidget只能使用标准的数据模型
  • 2020-12-27

    海盗分金币 题目 代码 题目 有5个海盗 相约进行一次帆船比赛 比赛中天气发生突变 他们被冲散了 恰巧 他们都先后经过途中的一个无名的荒岛 并且每个人都信心满满 觉得自己是第一个经过该岛的人 第一个人在沙滩上发现了一堆金币 他把金币分成5等
  • SAP ABAP ME23N 采购订单打印输出

    本人诚心接ABAP远程开发任务 价格公道 有需要的联系我 欢迎个人 甲方爸爸 乙方私信联系 完成的功能是ME23N 点击打印预览 客制化用户自己的打印模板 首先需要先配置打印输出 路径 spro gt 物料管理 gt 采购 gt 消息 gt
  • 【SQL Server DBA】日常巡检2:windows性能监控器

    性能监视器的各类指标 一 内存指标 1 Windows层面上的内存使用检查在检查SQL Server内存使用之前 DBA必须首先检查一下Windows层面的内存使用情况 Windows层面没有明显的内存压力 是SQL Server正常运行的
  • Github Blame、History 按钮什么意思?

    Github Blame History 按钮 是啥意思 blame 按行显示最新提交的信息 The blame command is a Git feature designed to help you determine who mad
  • percent percentile percentage有什么区别

    percent 百分之几 My mobile phone battery is currently at 10 percent 我的手机电池目前还有10 percentage 百分比 The percentage of students w
  • JetBrains IDE使用(更新中)

    简介 JetBrains IDE是JetBrains公司推出的IDE Integreated Development Environment 集成开发环境 包括IntelliJ IDEA PyCharm WebStorm等 该公司旗下的ID
  • 说说webpack中常见的Plugin?解决了什么问题?

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 webpack中的 Plugin 是什么 二 配置方式 1 通过配置文件导出对象中plugins属性传入new实例对象 如下所示 三 常见的Plugin 总结
  • uniapp ios圆角溢出不影藏的问题

    代码 list img position relative z index 1 overflow hidden height 154px text align center border radius 5px border 1px soli

随机推荐

  • Firefox报错——Gah. Your tab just crashed.

    Firefox报错 Gah Your tab just crashed 使用kali内置的firefox的时候报错了 看了一下好像没有可执行文件了 可能不小心删了吧 早看内置的不爽了 正好下个新的 在Kali官网下载linux的安装包 链接
  • 运算符

    文章目录 一 算术运算符 1 基本四则运算符有 加 减 乘 除 求余或求模 2 增量赋值运算符有 3 自增 自减运算符 二 关系运算符 关系运算符主要有 lt gt lt gt 三 逻辑运算符 逻辑运算符主要有 逻辑与 逻辑或 逻辑非 四
  • 安装配置mariadb

    记录下安装配置mariadb的经历 环境 ubuntu22 一 apt在线安装 apt代理配置 APT是Ubuntu系统中用于安装和升级软件包的工具 如果本地没有可用的软件包 APT将会连接到远程软件包服务器下载软件包 在某些情况下 用户需
  • 信息熵(Entropy)到底是用来衡量什么的?

    信息熵 Entropy 到底是用来衡量什么的 与Philip ZHANG商榷 思明 中国研究 zgyj1999 xiamian htm
  • 学习MQTT QoS的原理与应用

    MQTT QoS的原理与应用 学习QoS的原理与应用 文章目录 MQTT QoS的原理与应用 一 什么是服务质量 2 设置QoS 3 服务质量降级 4 使用步骤 1 引入PubSubClient库 二 保留消息 保留消息得到介绍 保留消息应
  • SQLI-LABS环境搭建及并进行拖库教程——解决MySQL注释问题--+

    1 SQLI LABS专有靶场搭建 1 1 SQLI LABS下载 SQLI LABS 是一个学习 SQL 注入的实验平台 下载地址 https github com Audi 1 sqli labs 1 2 Lamp环境搭建 在cento
  • seq2seq attentio

    encoder和decoder中的注意力机制 注意力机制的核心思想 在decoder的每一步 把encoder中的 所有向量提供给decoder模型 让decode根据自己当前的情况来选择自己需要的信息 例子 h1 2 3 是encoder
  • android 获取程序目录结构,Android开发程序的目录结构详解

    第一部分 c c 代码 Android系统源代码目录里面 hardware ril 目录包含了所有有关于telephony的底层代码 1 目录架构 20101215的git版本 ril CleanSpec mk include teleph
  • 关于fgets()函数的使用方法

    在读取字符串时 scanf 和转换说明符 s只能读取一个单词 gets 函数简单易用 它读取整行输入 直至遇到换行符 然后丢弃换行符 存储其余字符 并在这些字符的末尾添加一个空字符使其成为一个C字符串 但是出现一个问题 gets 函数无法检
  • VUE element-ui之form表单中input输入超过规定长度error提醒,并实时显示输入长度,可无限输入

    需求 输入超过规定长度error提醒 并实时显示输入长度 可无限输入 步骤 我的项目中使用校验比较多 所以进行简单的封装 新建js文件写入下面的函数 export function valieTextLength rule value ca
  • 第七章 React组件API

    在React中 常见的React组件API包含如下 1 设置状态 setState 2 替换状态 replaceState 3 强制更新 forceUpdate 要调用组件上的API 首先需要获取对组件的引用 在组件方法内部可以通过this
  • CTFshow web1

    打开是一个登录界面 用御剑扫描一下网站目录 发现有一个www zip可以被正常访问到 访问 www zip被下载 里边是网站的源码 login php 登录页 中能禁的基本都禁干净了 登录页面貌似没有注入的可能 reg php 注册页 也是
  • opengl 打开和关闭垂直同步方法

    垂直同步是涉及到显卡和显示器的一个概念 当开启了垂直同步 显卡在渲染完成一帧图像之后 显卡需要等待垂直同步信号的到来 否则无法绘制下一帧 启用垂直同步 将限制画面更新率和显示器一样 也就是限制了FPS 帧率 有关资料 没有完全证实 在nvi
  • Oracle 导出*.dmp

    数据导出 dmp 1 数据库实例orcl完全导出 用户名root 密码123456 导出到指定文件中 D export orcl dmp exp root 123456 101 10 28 1 orcl file D export orcl
  • 有空就看看的leetcode6——最长公共前缀(c++版)

    有空就看看的leetcode6 最长公共前缀 c 版 学习前言 题目 解法 学习前言 考试好难啊 题目 编写一个函数来查找字符串数组中的最长公共前缀 如果不存在公共前缀 返回空字符串 示例 1 输入 flower flow flight 输
  • 2万字雄文:饿了么核心交易系统 5 年演化史!

    我为什么会写这篇文章 究其缘由 一是自己在交易域做了 4 年 有很多只有我才知道 才能串起来的故事 想把这些记录并保留下来 二是发现后边的很多同学看交易体系时 一接触就是分布式 SOA 每日百万 千万数据量 只知道它是这个样子 很难理解背后
  • 微信小程序加密数据解密算法

    使用方法 go get github com xlstudio wxbizdatacrypt 引入方法 import github com xlstudio wxbizdatacrypt 使用示例 package main import f
  • JVM学习-Java内存结构(详细易懂)

    Java内存结构 1 JVM概述 2 程序计数器 2 1 定义 2 2 作用及特点解释 3 虚拟机栈 3 1 栈的特点 3 2 栈的演示 3 3 栈的问题辨析 3 4 栈的线程安全问题 3 5 栈内存溢出 StackOverflowErro
  • 常见的线性滤波和非线性滤波

    在OpenCV中给出了给出了3种常见的线性滤波和2种非线性滤波 其中线性滤波分别为方框滤波 均值滤波和高斯滤波 非线性滤波分别为中值滤波和双边滤波 关于它们的具体介绍后续会补充
  • 光线追踪(RayTracing)算法

    1 Forward Tracing 假设有一个每次只发射一个光子的光源 光子从光源发出并沿着直线路径行进 直至撞击到物体表面 忽略光子的吸收 该光子会以随机的方向反射 如果光子撞击到我们的眼睛表面 则我们会看到光子被反射的点 现在从计算机图