太极图形课——渲染——光线追踪实战第一部分呢

2024-06-05 01:12

本文主要是介绍太极图形课——渲染——光线追踪实战第一部分呢,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

根据概念部分我们逐步通过太极实现光线追踪

总共可以分为5步

第一步:如何发射出一道光?

首先明确何为一道光,光从我们眼睛(摄像机)射出,那么在三维虚拟世界里,我们可以认为这道光就是一条射线,在三维世界里,一条射线可以由一个点和一个向量定义

任何在这条射线上的点,我们都可以用一个标量t来表示,这个标量的值代表了这个点到射出去的原点的距离

那么我们如何把这样一条射线放进我们所定义的虚拟世界中呢,首先需要设定的就是在这个虚拟世界中我们眼睛(摄像机)的位置,这个位置通过三维世界的坐标一个三维的数组就可以表达了,第二就是定义我们看的方向,也就是方向向量,也通过一个三维的数组表达

在概念中说,最后我们要将三维的物体投影在眼前的屏幕上就可以了,那么我们就需要放置屏幕,我们所看的方向穿过这个屏幕的中心,这个屏幕垂直于我们的视线

现在屏幕的位置还没有确定,首先我们需要确定屏幕和我们眼睛的距离,再确定屏幕屏幕的方向,我们设定一个三维向量来确定,最后就是屏幕的大小,这个我们通过设定一个fov来表示

通过fov可以求出屏幕的半宽和半长,宽由长决定,取决于你需要几比几的屏幕,例如16:9,有了这些我们设定一个以屏幕中心为原点的坐标系uvw,最后可以确定眼睛或者说摄像机左下角出发的点,并确定其水平和垂直的向量

此时我们就已经准备好发射射线

#首先定义一个世界坐标系,其中有眼睛或者说摄像机的位置
lookfrom[None] = [x,y,z]
#定义朝向
lookat[None] = [x,y,z]
#定义屏幕和其中心点
theta = 1.0/3.0 *pi #fov设置
half_height = ti.tan(theta/2.0) *distance
half_width = aspect_ratio * half_height * distance
w = (lookfrom[None] - lookat[None]).normalized()
u = (upp[None].cross(w)).normalized()
v = w.cross(u)
#可以得到屏幕的视点位置
cam_lower_left_corner[None] = (lookfrom[None] - half_width*u - half_height *v - w)*distance 
cam_horizational[None] = 2* half_width * u * distance 
cam_vertical[None] = 2 * half_height * v *distance
#发射光线
u = float(j)/res_x
v = float(i)/res_Y
ray.direction = cam_lower_left_corner[None] + u * cam_horizational[None] + v * cam_vertical[None] - lookfrom[None]
#pixel块是一个像素点方块,我们可以将其放在正中间
u = float(i + 0.5)/res_x
v = float(j + 0.5)/res_y

由于像素是一个方块,我们还可以把这个射线正好移动到点的中心

第二步: 如何将光和物体求交

之前已经了解到一个视线由一个射线表示,射线上的每一个点可以通过一个标量t来表示,那么怎么实现物体和实现的求交呢,对于一个圆来说。我们可以将圆用一个参数方程来表示,然后将点用t来代替我们就可以得到下列的方程

将方程简化就可以获得一个一元二次方程

通过求根公式韦达定理,可以判断是否有相交,相交的点是哪一个,我们需要去第一个正根,在计算机中由于有时候会出现0.0001这种明显是物体没有相交而是反射的正根,因此需要添加一个门槛,例如正根至少要大于0.001

目前教程所给代码中仅仅只实现了与圆的相交,实际上还可以实现和平面,三角形实现相交,例如对于一个平面来说,我们

的参数方程可以定义为平面上任意两个点所构成的向量和平面的法向量垂直,也就是点乘为0,将任意一点用视线的点代替

可以获得的根的方程为向量d和法向量点乘不为0,也就是这两个方向不垂直的时候,一定有一个点

如果为点乘为0,也分为从平面出发导致与平面重合以及不从平面出发,永远没有交点

进一步如何判断有点的话是否该点在三角形内

此时需要引入的概念是重心的概念,具体概念如下图,三个三角形的面积相加等于整个三角形说明这个点在三角形内

这个重心的概念可以推广到四面体上

此时就可以判断三角形网格的相交了

最后可以得到两种方法,一种是隐式积分,找到面的定义,将点的定义代入其中,最后得到一个高纬的方程,简化后都是一个一元二次方程,第二种方法遍历全部的三角形面片,找到点在哪个三角形里面

这篇关于太极图形课——渲染——光线追踪实战第一部分呢的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变