Games101Homework【6】Acceleration structure(Including framework analysis)

Code Analysis:

friend:

C++中友元(友元函数和友元类)的用法和功能_friend class a<b>-CSDN博客

[C++:不如Coding](11):友元函数与友元类_哔哩哔哩_bilibili

Here is a simple explanation:

By using the mechanism of classes, data hiding and encapsulation are achieved. Data members of a class are usually defined as private, while member functions are generally defined as public, thus providing an interface for communication between the class and the outside world. However, sometimes it is necessary to define functions that are not part of the class but need frequent access to the class's data members. In such cases, these functions can be defined as friend functions of the class. In addition to friend functions, there are also friend classes, both of which are collectively referred to as friends. The purpose of friends is to improve the efficiency of the program (by reducing the time overhead of type checking and security checks, etc.). However, they undermine the encapsulation and hiding of the class, allowing non-member functions to access the class's private members.

Why use friends: You don't have to write a public method for a special case separately (for example, for a man and a woman, there is a marry method that is generally called only once during the lifecycle of these two classes. If you give the man or woman class a public method, marry, it is unnecessary and would make the class overly complex).


Operator overloading:

        C++运算符重载_哔哩哔哩_bilibili

std::Move:

The functionality of std::move is to convert a left-value into an r-value reference, and return that r-value reference, allowing the value to be used via the r-value reference for move semantics (move constructor or move assignment operator).

std::move()与移动构造函数_std::move的作用-CSDN博客

Architecture:

Let's look at the picture first:

The logical architecture is exceptionally clear now, and I've placed the source code (with comments) in another blog.

Games101Homework【6】Code Part-CSDN博客

Principle:

Checking if a ray intersects with a plane.:

Determine the entry point and exit point:

BVH Core Algorithm (Recursive):

Code: 

Render():

Transform the manually added vectors into a new Ray object:

void Renderer::Render(const Scene& scene)
{std::vector<Vector3f> framebuffer(scene.width * scene.height);float scale = tan(deg2rad(scene.fov * 0.5));float imageAspectRatio = scene.width / (float)scene.height;Vector3f eye_pos(-1, 5, 10);int m = 0;for (uint32_t j = 0; j < scene.height; ++j) {for (uint32_t i = 0; i < scene.width; ++i) {// generate primary ray directionfloat x = (2 * (i + 0.5) / (float)scene.width - 1) *imageAspectRatio * scale;float y = (1 - 2 * (j + 0.5) / (float)scene.height) * scale;// TODO: Find the x and y positions of the current pixel to get the// direction//  vector that passes through it.// Also, don't forget to multiply both of them with the variable// *scale*, and x (horizontal) variable with the *imageAspectRatio*Ray ray(eye_pos, normalize(Vector3f(x, y, -1)));// Don't forget to normalize this direction!framebuffer[m++] =scene.castRay(ray,scene.maxDepth);}UpdateProgress(j / (float)scene.height);}UpdateProgress(1.f);// save framebuffer to fileFILE* fp = fopen("binary.ppm", "wb");(void)fprintf(fp, "P6\n%d %d\n255\n", scene.width, scene.height);for (auto i = 0; i < scene.height * scene.width; ++i) {static unsigned char color[3];color[0] = (unsigned char)(255 * clamp(0, 1, framebuffer[i].x));color[1] = (unsigned char)(255 * clamp(0, 1, framebuffer[i].y));color[2] = (unsigned char)(255 * clamp(0, 1, framebuffer[i].z));fwrite(color, 1, 3, fp);}fclose(fp);    
}

Triangle::getIntersection():

Calculate intersection information:

/*** 获取射线与三角形的交点信息* * @param ray 射线对象,包含射线的起点和方向* @return Intersection 结构体,包含交点是否发生、交点坐标、交点到射线起点的距离、*         对应的物体指针、交点处的法向量和材质信息*/
inline Intersection Triangle::getIntersection(Ray ray)
{Intersection inter; // 初始化交点信息结构体// 如果射线方向与三角形法向量的点积大于0,则射线方向与三角形面向反,不产生交点if (dotProduct(ray.direction, normal) > 0)return inter;double u, v, t_tmp = 0;// 计算pvec,这是进行交点计算的一部分Vector3f pvec = crossProduct(ray.direction, e2);// 计算行列式值det,用于后续交点计算double det = dotProduct(e1, pvec);// 如果行列式的绝对值小于EPSILON,表示方向向量几乎平行,不产生交点if (fabs(det) < EPSILON)return inter;// 计算行列式的倒数,用于简化后续计算double det_inv = 1. / det;// 计算tvec,这是计算u参数的一部分Vector3f tvec = ray.origin - v0;// 计算参数u,如果u不在0到1之间,则交点不在三角形上u = dotProduct(tvec, pvec) * det_inv;if (u < 0 || u > 1)return inter;// 计算qvec,用于计算v参数Vector3f qvec = crossProduct(tvec, e1);// 计算参数v,如果v不在0到1之间,或u+v不在0到1之间,则交点不在三角形上v = dotProduct(ray.direction, qvec) * det_inv;if (v < 0 || u + v > 1)return inter;// 计算临时距离参数t_tmp,用于进一步判断交点是否成立t_tmp = dotProduct(e2, qvec) * det_inv;// 判断t_tmp是否小于0,若小于0,则交点在射线的起点之后,不成立if(t_tmp<0){return inter;}// 如果以上所有条件都满足,则更新交点信息为有效交点inter.happened = true;inter.coords = ray(t_tmp); // 计算交点坐标inter.distance = t_tmp; // 保存交点到射线起点的距离inter.obj = this; // 保存对应的三角形对象指针inter.normal = normal; // 保存交点处的法向量inter.m = m; // 保存材质信息return inter;
}

IntersectP(): 

"Solve equations to calculate tEnter and tExit. Based on the direction of the ray, if it is emitted in the non-positive direction, then the smaller negative t is the exit point, and the larger one is the entry point (dirIsNeg).

inline bool Bounds3::IntersectP(const Ray& ray, const Vector3f& invDir,const std::array<int, 3>& dirIsNeg) const
{// invDir: ray direction(x,y,z), invDir=(1.0/x,1.0/y,1.0/z), use this because Multiply is faster that Division// dirIsNeg: ray direction(x,y,z), dirIsNeg=[int(x>0),int(y>0),int(z>0)], use this to simplify your logic// TODO test if ray bound intersectsVector3f tEnter,tExit;tEnter=  (pMin-ray.origin)*invDir;tExit =  (pMax-ray.origin)*invDir;if(!dirIsNeg[0]){std::swap(tEnter.x,tExit.x);}if(!dirIsNeg[1]){std::swap(tEnter.y,tExit.y);}if(!dirIsNeg[2]){std::swap(tEnter.z,tExit.z);}float tenter,texit;tenter=std::max(tEnter.x,std::max(tEnter.y,tEnter.z));texit=std::min(tExit.x,std::min(tExit.y,tExit.z));return tenter<=texit&&texit>=0;}

getIntersection():

Implementing the core algorithm:

Intersection BVHAccel::getIntersection(BVHBuildNode* node, const Ray& ray) const
{Intersection isect;// TODO Traverse the BVH to find intersectionif(!node->bounds.IntersectP(ray,ray.direction_inv,std::array<int,3>{ray.direction.x>0,ray.direction.y>0,ray.direction.z>0})) return isect;if((!node->left)&&(!node->right)){return node->object->getIntersection(ray);}auto hit1=getIntersection(node->left,ray);auto hit2=getIntersection(node->right,ray);return hit1.distance<hit2.distance?hit1:hit2;
}

 Result:

cool!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/812754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维数组---刷题

一维数组不想更了&#xff0c;弄点二维数组&#xff01; 1.对角线 已知一个6*6的矩阵&#xff0c;把矩阵两条对角线上的元素加上10&#xff0c;然后输出这个新矩阵。 思路 题目简单&#xff0c;6*636&#xff0c;可以得知有36个元素。数组就定义成a[7][7]&#xff0c;难点在与…

软考数据库---3.关系数据库

3.1 名词 属性分类 数据库实体属性分类主要包括以下几个方面&#xff1a; 标识属性 (Key Attribute / Identifier): 这些属性是用来唯一识别实体实例的关键属性&#xff0c;也称为主键&#xff08;Primary Key&#xff09;。在数据库表中&#xff0c;每个实体的实例&#xff0…

深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! Doris是一款高性能、开源的实时分析数据仓库&#xff0c;旨在为用户提供毫秒级查询响应、高并发、高可用以及易于扩展的OLAP解决方…

【深度学习实战(5)】使用OPENCV库实现自己的letter_box操作

一、letter_box 深度学习模型输入图片的尺寸为正方形&#xff0c;而数据集中的图片一般为长方形&#xff0c;粗暴的resize会使得图片失真&#xff0c;采用letterbox可以较好的解决这个问题。该方法可以保持图片的长宽比例&#xff0c;剩下的部分采用灰色填充。 二、代码 本例…

c语言->贪吃蛇实战技巧结合EasyX简单实现页面管理(简单实现)

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1. 游戏背景 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅…

AndroidAutomotive模块介绍(二)应用及接口介绍

前言 上一篇文章中从整体角度描述了 Android Automotive 模块。本篇文章将对 Android Automotive 中的 APP 以及 API 部分展开描述。 上一篇&#xff1a;AndroidAutomotive模块介绍&#xff08;一&#xff09;整体介绍 下一篇&#xff1a;AndroidAutomotive模块介绍&#xff0…

python-study-day2

pycharm注释(也可修改) 快捷键ctrl /手敲一个 " # " 这个是单行注释""" """ 左边这个三个引号可以完成多行注释 基础知识 常用的数据类型 def hello(self):print("Hello")print(type(1)) print(type("1"…

图片超分辨率重构实战——SRGAN

数据与代码链接见文末 论文地址:Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network https://arxiv.org/abs/1609.04802v4 1.概述 通常来说,分辨率越低,图像越模糊,分辨率越高,图像越清晰,图像超分辨率重构就是将分辨率低的图像重…

OceanBase V4.2 MySQL模式下,如何通过DBLINK实现跨数据源访问

概述 跨数据源访问可通过 DBLINK&#xff08;以下简称DBLINK&#xff09;实现&#xff0c;从而使得业务代码能够像访问本地数据库一样轻松访问远端数据库。原先&#xff0c;DBLINK主要服务于Oracle模式&#xff0c;但由于OceanBase 的MySQL模式租户同样存在访问远端数据库的需…

基于Springboot+Vue的Java项目-旅游网站系统(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

K-means和逻辑回归

逻辑回归 一个事件的几率是该事件发生的概率/该事件不发生的概率&#xff1a;P/&#xff08;1-P&#xff09; 对数几率是&#xff1a;log(P/&#xff08;1-P&#xff09;) **考虑对输入x分类的模型&#xff1a;**log(P/&#xff08;1-P&#xff09;)wx 则 Pexp(wx)/(exp(w*x)…

Ubuntu上安装Python3.11-源码编译

1、下载依赖 sudo apt install -y wget build-essential libreadline-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev 2、上传文件 &#xff0c;解压并进入 tar -xf Python-3.11.0.tar.xz 3、编译 cd Pyt…

跟TED演讲学英文:The dark side of competition in AI by Liv Boeree

The dark side of competition in AI Link: https://www.ted.com/talks/liv_boeree_the_dark_side_of_competition_in_ai Speaker:Liv Boeree Date: October 2023 文章目录 The dark side of competition in AIIntroductionVocabularyTranscriptSummary后记 Introduction Co…

实验5 流程图和盒图ns图

一、实验目的 通过绘制流程图和盒图&#xff0c;熟练掌握流程图和盒图的基本原理。 能对简单问题进行流程图和盒图的分析&#xff0c;独立地完成流程图和盒图设计。 二、实验项目内容&#xff08;实验题目&#xff09; 1、用Microsoft Visio绘制下列程序的程序流程图。 若…

浏览器工作原理与实践--渲染流水线:CSS如何影响首次加载时的白屏时间

在上一篇文章中我们详细介绍了DOM的生成过程&#xff0c;并结合具体例子分析了JavaScript是如何阻塞DOM生成的。那本文我们就继续深入聊聊渲染流水线中的CSS。因为CSS是页面中非常重要的资源&#xff0c;它决定了页面最终显示出来的效果&#xff0c;并影响着用户对整个网站的第…

数据结构复习指导之绪论(数据结构的基本概念)

文章目录 绪论&#xff1a; 考纲内容 知识框架 复习提示 1.数据结构的基本概念 1.1基本概念和术语 1.数据 2.数据元素 3.数据对象 4.数据类型 5.数据结构 1.2数据结构三要素 1.数据的逻辑结构 2.数据的存储结构 3.数据的运算 绪论&#xff1a; 考纲内容 算法时…

开源AI图像识别:支持文件批量识别快速对接数据库存储

随着数字化转型的不断深入&#xff0c;图像识别技术在各行各业中的应用越来越广泛。文件封识别作为图像识别技术的一个分支&#xff0c;能够有效地提高文件处理的自动化程度和准确性。本文将探讨文件封识别技术的原理、应用场景以及如何将识别后的内容批量对应数据库字段进行存…

CSS特效---HTML+CSS实现3D旋转卡片

1、演示 2、一切尽在代码中 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title&…

Day23_学点儿Java_多态复习

1 做错的选择题 Java中的多态性是通过以下哪个机制实现的&#xff1f;&#xff08;&#xff09; A. 方法重载 B. 方法覆盖 C. 抽象类 D. 接口2 多态复习 2.1 学点儿Java_Day7_继承、重载、重写、多态、抽象类 2.2 面向对象四大基本特征 封装、抽象、继承、多态 封装 面向…

Linux文件IO

文章目录 1.文件操作的知识点2.文件的理解3.标记位4.文件的本质5.文件的应用5.1 重定向5.1.1 重定向的接口5.1.2 缓冲区的理解 6.文件描述符2(stderr)的深入理解7.磁盘文件7.1 物理磁盘7.2 磁盘的存储结构7.3 磁盘存储的逻辑7.4 细化磁盘存储 8.dd指令挂载 1.文件操作的知识点 …