Games101作业5
1.实现Renderer.cpp 中的 Render():为每个像素生成光线
这里你需要为每个像素生成一条对应的光 线,然后调用函数 castRay() 来得到颜色,最后将颜色存储在帧缓冲区的相 应像素中。
我们要做的就是将屏幕空间下的坐标最后转换到世界空间的坐标
这里一开始是处于屏幕空间坐标下的,如下图,这里假设原点在左上角,opengl原点在左下角,dx原点在左上角,那么首先想到的是将i,j分别加0.5取得像素中心坐标
接着将坐标变换到NDC空间,NDC空间是一个长宽高取值范围为[-1,1]的立方体,超过这个范围的顶点,会被GPU剪裁。注:在DirectX里面,NDC的z方向取值范围是[0,1]
DX下的NDC空间如下图,要转换到NDC空间下,首先要用x,y分别除以屏幕的宽度贺高度。然后NDC空间需要将坐标轴原点变回到屏幕中间位置。
i方向即宽方向,[0,1]->[-1,1],因为变化是线性的,很容易得到 i = 2*i-1。
j方向即高方向,[0,1]->[1,-1],因为变化是线性的,很容易得到 i = -2*i+1
最后要将坐标转换到世界空间,要解决两个问题:
①横纵方向的长度并不是1:1的;
②物体本身并不是在[-1,1]的,[-1,1]是缩放后的范围。
解决办法:
①imageAspectRatio即宽高比,是原本scene的宽高比,所以要想恢复原始的比例需要用 宽 * 宽高比,即 x * imageAspectRatio。
②scale为一半可看角度(fov/2)的tan值,即下图tan(α/2),它代表了原本图像屏幕高度与图像到X-Y平面距离的比值,又由代码已给出的 Vector3f dir = Vector3f(x, y, -1) ,可以知道原本的图像屏幕距离X-Y平面为1,所以scale即为原本的图像高度,而现在的图像高度为1,所以令x,y同时乘以scale即可得到原始世界坐标下的坐标。
综上所述,最后直接给出代码计算
void Renderer::Render(const Scene& scene)
{std::vector<Vector3f> framebuffer(scene.width * scene.height);//float scale = std::tan(deg2rad(scene.fov * 0.5f));//宽高比float imageAspectRatio = (float)scene.width / (float)scene.height;// Use this variable as the eye position to start your rays.Vector3f eye_pos(0);int m = 0;for (int j = 0; j < scene.height; ++j){for (int i = 0; i < scene.width; ++i){// generate primary ray directionfloat x = (2 * (((float)i + 0.5) / scene.width) - 1)* imageAspectRatio * scale;float y = (1.0 - 2 * ((float)j + 0.5) / 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* //vector = op,说明scene在z=-1,故znear距离人眼距离=1 Vector3f dir = normalize(Vector3f(x, y, -1)); // Don't forget to normalize this direction!framebuffer[m++] = castRay(eye_pos, dir, scene, 0);}UpdateProgress(j / (float)scene.height);}// 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] = (char)(255 * clamp(0, 1, framebuffer[i].x));color[1] = (char)(255 * clamp(0, 1, framebuffer[i].y));color[2] = (char)(255 * clamp(0, 1, framebuffer[i].z));fwrite(color, 1, 3, fp);}fclose(fp);
}
到这一步输出的结果:
window下查看ppm图片貌似需要用到第三方软件,这里给出我用的一个网站:
在线查看 PPM 文件的免费在线工具 - ImageToStl
2.Triangle.hpp 中的 rayTriangleIntersect():实现视射线与三角形相交
主要就是根据这个公式分别带入不同的参数就可以
origin是相机的位置,dir是射出的方向
bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig,const Vector3f& dir, float& tnear, float& u, float& v)
{// TODO: Implement this function that tests whether the triangle// that's specified bt v0, v1 and v2 intersects with the ray (whose// origin is *orig* and direction is *dir*)// Also don't forget to update tnear, u and v.Vector3f E1 = v1 - v0, E2 = v2 - v0 ;Vector3f S = orig - v0,S1 = crossProduct(dir, E2), S2 = crossProduct(S, E1);if (dotProduct(S1, E1) <= 0) return false;tnear = dotProduct(S2, E2) / dotProduct(S1, E1);u = dotProduct(S1, S) / dotProduct(S1, E1);v = dotProduct(S2, dir) / dotProduct(S1, E1);if (tnear >= 0 && u >= 0 && v >= 0 && (1 - u - v) >= 0) return true;return false;
}
最后的结果
相关文章:
Games101作业5
1.实现Renderer.cpp 中的 Render():为每个像素生成光线 这里你需要为每个像素生成一条对应的光 线,然后调用函数 castRay() 来得到颜色,最后将颜色存储在帧缓冲区的相 应像素中。 我们要做的就是将屏幕空间下的坐标最后转换到世界空间的坐标…...
Golang解决跨域问题【OPTIONS预处理请求】
Golang解决跨域问题 前置知识:跨域问题产生条件及原因 跨域是是因为浏览器的同源策略限制,是浏览器的一种安全机制,服务端之间是不存在跨域的。 所谓同源指的是两个页面具有相同的协议、主机和端口,三者有任一不相同即会产生跨域…...
复试 || 就业day05(2023.12.31)算法篇
文章目录 前言找不同最长回文串找到所有数组中消失的数字下一个更大元素 I键盘行 前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫文章题目大多来自于 leetcode,当然也可能来自洛谷或其他刷题平台 💫…...
Spring-4-代理
前面提到过,在Spring中有两种类型的代理:使用JDK Proxy类创建的JDK代理以及使用CGLIB Enhancer类创建的基于CGLIB的代理。 你可能想知道这两种代理之间有什么区别,以及为什么 Spring需要两种代理类型。 在本节中,将详细研究代理…...
设计模式:抽象工厂模式(讲故事易懂)
抽象工厂模式 定义:将有关联关系的系列产品放到一个工厂里,通过该工厂生产一系列产品。 设计模式有三大分类:创建型模式、结构型模式、行为型模式 抽象工厂模式属于创建型模式 上篇 工厂方法模式 提到工厂方法模式中每个工厂只生产一种特定…...
C语言中的Strict Aliasing Rule
文章目录 前言没有警告不代表没有问题目前的应对方法 前言 很久没写了,水一篇。 最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werrorstrict-aliasing]查了下…...
单字符检测模型charnet使用方法,极简
Git链接 安装按照上面的说明,说下使用。 把tools下面的test做了一点修改,可以读取一张图片,把里面的单个字符都检测和识别出来。 然后绘制到屏幕上。 import torch from charnet.modeling.model import CharNet import cv2, os import num…...
Erlang、RabbitMQ下载与安装教程(windows超详细)
目录 安装Erlang 1.首先安装RabbitMQ需要安装Erlang环境 2.点击下载好的.exe文件进行傻瓜式安装,一直next即可 3.配置Erlang环境变量 安装RabbitMQ 1.给出RabbitMQ官网下载址:Installing on Windows — RabbitMQ,找到 2.配置RabbitMQ环境变量࿰…...
2023年终总结丨很苦,很酷!
文章目录 个人简介丨了解博主写在前面丨博主介绍年终总结丨博主成就年终总结丨博主想说年终总结丨学习芝士年终总结丨未来展望写在后面丨新年快乐 个人简介丨了解博主 主页地址:https://blog.csdn.net/m0_68111267 荣誉身份 ⭐2022年度CSDN 社区之星 Top6 ⭐2023年…...
鸿蒙 DevEco Studio 3.1 入门指南
本文主要记录开发者入门,从软件安装到项目运行,以及后续的学习 1,配置开发环境 1.1 下载安装包 官网下载链接 点击立即下载找到对应版版本 下载完成,按照提示默认安装即可 1.2 下载SDK及工具链 运行已安装的DevEco Studio&…...
ubuntu多用户环境dockerbug,卸载重装docker流程
之前不小心误操作删除重装docker,结果删除没成功,更没法重装,每次apt install都会报一个docker错误,虽然不影响软件的常规安装~但是现在还是需要装一个完整docker,还是选择删除一下,重点是关闭服…...
微信小程序开发系列-09自定义组件样式特性
微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序…...
数据结构 模拟实现LinkedList单向不循环链表
目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size得到单链表的长度方法 (3)addFirst头插方法 (4)addLast尾插方法 (5…...
2023-12-24 LeetCode每日一题(收集足够苹果的最小花园周长)
2023-12-24每日一题 一、题目编号 1954. 收集足够苹果的最小花园周长二、题目链接 点击跳转到题目位置 三、题目描述 给你一个用无限二维网格表示的花园,每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| |j| 个苹果。 你将会买下正中心坐…...
Oracle 19c OCP 1z0 082考场真题解析第17题
考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为云贝教育郭一军guoyJoe原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 17. Which three …...
掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接
掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接。 用来爬虫的十几个Python库。只要正确选择适合自己的Python库才能真正提高爬虫效率,到达高效爬虫目的。 1.PyQuery from pyquery import PyQuery as …...
模型 KANO卡诺模型
本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。需求分析。 1 卡诺模型的应用 1.1 餐厅需求分析故事 假设你经营一家餐厅,你想了解客户对你的服务质量的满意度。你可以使用卡诺模型来收集客户的反馈,并分析客户的…...
启明智显开源项目分享|基于Model 3c芯片的86中控面板ZX3D95CM20S-V11项目软硬件全开源
前言: 本文为4寸 480*480 RGB接口IPS全面触屏的86中控面板(RT-ThreadLVGL)软硬件开源干货内容,该项目是综合性非常强的RTOS系列项目!项目主控芯片使用 Model 3c,整体实现了简化版本的86中控面板的功能需求…...
Kind创建k8s - JAVA操作控制
kind 简介kind 架构安装 Kind (必备工具)docker官网kubectl官网kind官网校验安装结果 关于kind 命令 安装一个集群查看当前 Kubernetes 集群中的节点信息。查看当前命名空间下中的Pod(容器实例)的信息。使用 kind create cluster 安装,关于安…...
Qt sender()函数
sender函数原型: QObject *sender() const; 如果在由信号激活的插槽中调用该函数,返回指向发送信号的对象的指针,否则返回0,该指针仅在从该对象的线程上下文调用此函数的槽执行期间有效。 主要代码如下: 其中运用了Q…...
Java开发框架和中间件面试题(6)
目录 61.什么是Spring Batch? 62.请举例解释Required与Qualifier注解? 61.什么是Spring Batch? Spring batch是一个轻量级的,完善的批处理框架,他主要的目的在于帮助企业建立健壮,高效的批处理应用。Spri…...
附录E SQL入门之SQL保留字
本专栏目录 第1课 SQL入门之了解SQL 第2课 SQL入门之检索数据 第3课 SQL入门之排序检索数据 第4课 SQL入门之过滤数据 第5课 SQL入门之高级数据过滤 第6课 SQL入门之用通配符进行过滤 第7课 SQL入门之创建计算字段 第8课 SQL入门之使用数据处理函数 第9课 SQL入门之汇总数据 第…...
thinkphp6.0升级到8.0
目录 一:升级过程 二:报错处理 最近写的项目需要使用thinkphp8.0,之前的老项目需要从php6.0升级到8.0,特此记录下升级过程。 一:升级过程 查看版本: php think version,我目前的版本是6.1.4 生成thin…...
机器学习(一) -- 概述
系列文章目录 机器学习(一) -- 概述 机器学习(二) -- 数据预处理 未完待续…… 目录 系列文章目录 前言 一、机器学习定义(是什么) 二、机器学习的应用(能做什么) 三、***机器…...
SpringBoot定时监听RocketMQ的NameServer
问题分析 自己在测试环境部署了RocketMQ,发现namesrv很容易挂掉,于是就想着监控,挂了就发邮件通知。查看了rocketmq-dashboard项目,发现只能监控Broker,遂放弃这一路径。于是就从报错的日志入手,发现最终可…...
电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理
在数字化时代,采购管理也正经历着前所未有的变革。全过程数字化采购管理成为了企业追求高效、透明和规范的关键。该系统通过Spring Cloud、Spring Boot2、Mybatis等先进技术,打造了从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通过…...
各部门请注意,VELO维乐潮流骑士尼莫出街啦,快来加入吧!
VELO潮流骑士丨车界“小学生”尼莫,下面是来自她的自诉: 大家好!我是尼莫,一枚骑车届的“小学生”,我爱上骑车已经有一年的时间啦!在这一年的时间里,骑车改变了我很多:爱上…...
Flutter配置Android和IOS允许http访问
默认情况下,Android和IOS只支持对https的访问,如果需要访问不安全的连接,也就是http,需要做以下配置。 Android 在res目录下的xml目录中(如果不存在,先创建xml目录),创建一个xml文件network_security_con…...
[设计模式 Go实现] 创建型~抽象工厂模式
抽象工厂模式用于生成产品族的工厂,所生成的对象是有关联的。 如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。 比如本例子中使用RDB和XML存储订单信息,抽象工厂分别能生成相关的主订单信息和订单详情信息。 如果业务逻辑中需要替换使用的时候…...
移动端开发框架mui代码在安卓模拟器上运行(HbuilderX连接到模拟器)
开发工具 HBuilder X 3.8.12.20230817 注意:开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。 1、电脑下载安装安卓模拟器 我这里使用的是 夜神模拟器 ,也可以选择其他安卓模拟器 夜神模拟器官网:夜神安…...
upload-labs Pass-03(黑名单验证,特殊后缀)问题纠正
php任何后缀名解析 背景:为了验证php解析不依靠后缀名,可以是任何后缀名,纠正upload-labs Pass-03(黑名单验证,特殊后缀)里所说的几个固定的后缀名理论是错误的。1 部署1.1 环境准备1.1.1 系统、内核&#…...
微信小程序-父子页面传值
父子页面传值 父页面向子页面传值 方法一: 父页面: 1. /page/xxx/xxx?id1子页面: onLoad:function(option){ }方法二 <bindtap“func” data-xxx””> 子页面向父页面传值 定义父子页面 父页面:hotspot 子页面&a…...
【JavaScript】浮点数精度问题
✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…...
使用axios发送get和post请求
使用axios发送get和post请求的方法如下: 1.发送GET请求: axios.get(url).then(response > {// 请求成功的处理逻辑console.log(response.data);}).catch(error > {// 请求失败的处理逻辑console.error(error);});2.发送POST请求: ax…...
【基于VirtualBox及openEuler20.03 TLS SP1编译openGauss2.1.0源码】
【openEuler 20.03 TLS编译openGauss2.1.0源码】 一、安装环境二、安装步骤 一、安装环境 项目Value虚拟机virtualbox操作系统openEuler 20.03 TLSopenGauss2.1.0openGauss-third_party2.1.0 二、安装步骤 以下操作需要在root用户下执行 编辑/etc/selinux/config vim /etc/s…...
hibernate 使用注解+拦截器实现自动开启、关闭session,提交、回滚事务
hibernate 使用注解+注解拦截器实现自动开启、关闭session,开启、提交、回滚事务 项目为springboot项目 ,springboot版本为:2.5.11, hiernate-core5.4.3 版本。spring-xxx 等为5.3.17版本 注意:在spring-xxx4.x版本+ hiernate-core5.x.x版本中,hibernate的配置 true是有效的…...
Solidworks学习笔记
本内容为solidworks的学习笔记,根据自己的理解进行记录,部分可能不正确,请自行判断。 学习视频参考:【SolidWorks2018视频教程 SW2018中文版软件基础教学知识 SolidWorks自学教程软件操作教程 sw视频教程 零基础教程 视频教程】 h…...
Redis经典五大类型源码及底层实现(一)
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术🔥如果感觉博主的文章还不错的…...
数据库闭包求法 附相关习题及解析
闭包就是由一个属性直接或间接推导出的所有属性的集合 以下是写的比较科学规范的闭包求解方法,设X和Y均为关系R的属性集的子集,F是R上的函数依赖集,若对R的任一属性集B,一旦X→B,必有B⊆Y,且对R的任一满足…...
idea利用JRebel插件,无需重启,实现Spring Boot项目热重载,节省开发时间和精力!
插件介绍 官方介绍 翻译过来的意思是: JRebel 是一款提高开发效率的工具,允许开发者立即重新加载代码更改。它跳过了在Java开发中常见的重新构建、重启和重新部署循环。JRebel 能够让开发者在相同的时间内完成更多工作,并且在编码时能够保持…...
学习体系结构 - AArch64内存管理
学习体系结构 - AArch64内存管理 Learn the architecture - AArch64 memory management Version 1.2 个人的英语很一般,对拿不准的翻译校准在后面添加了英文原文。 1、 概述 本指南介绍了AArch64中的内存转换,这是内存管理的关键。它解释了如何将虚拟地…...
Vue3 精通指南:如何在 setup 函数中巧妙利用 Vuex
在 Vue 3 中,如果你使用了组合式 API(Composition API),你可以通过 setup 函数来设置组件的响应式状态和逻辑。要在 setup 函数中访问 Vuex 的 $store,你可以使用 useStore 钩子,它是 Vuex 4 为 Vue 3 提供…...
Linux 服务器安全策略技巧:启用账户锁定策略
Linux 服务器安全策略技巧:启用账户锁定策略 在Linux服务器上,启用账户锁定策略是一种重要的安全措施。通过锁定账户,可以防止未经授权的访问和恶意活动。本文将介绍如何在Linux服务器上启用账户锁定策略。 什么是账户锁定策略? 账户锁定策略是一种安全措施,用于限制对…...
野火霸道-V2+3.2寸屏+FreeRTOS+LVGL移植
摘要 基于野火霸道-V23.2寸屏的开发板,下载器为STLINK分为两个版本,FreeRTOS和裸机版本 裸机 裸机准备 lvgl v8.2版本的源码野火的《触摸画板-3.2寸》与《基本定时器》的代码例程 移植 将基本定时器代码移植到触摸画板-3.2寸的例程中,…...
操作教程|MeterSphere UI测试+VNC:简单、快捷地查看UI测试实时执行详情
编者注:本文为CSDN博主hxe116的原创文章。 原文链接为:https://blog.csdn.net/hxe116/article/details/134714960?spm1001.2014.3001.5502 作为一款一站式的开源持续测试平台,MeterSphere涵盖了测试跟踪、接口测试、UI测试和性能测试等功能…...
工具--Git详解
在当今的数字时代,版本控制系统已成为开发人员和团队之间协作的重要工具。其中,Git是最受欢迎的版本控制系统之一。它不仅在软件开发中广泛使用,还被应用于许多其他领域。在这篇博客中,我们将深入了解Git的工作原理、基本命令以及…...
windows server 2022 启用SYN攻击保护
2023.12.28 SYN攻击是什么: SYN攻击是黑客攻击的常用手段,也是最容易被利用的一种攻击手法,属于DDoS攻击的一种。它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。 SYN攻击包括大量TCP连接的第一个包&…...
汽车保养软件app开发步骤
“增强您的动力,为您的旅程加油——每一刻都讲述着关爱的故事。构建汽车维护软件app,为您的车辆提供数字化的维修站,从而开启长寿之路。智能驾驶、互联驾驶、自信驾驶。” 疯狂地搜索旧收据并猜测上次换油时间的日子已经一去不复返了。如果您…...
【HarmonyOS】ArkTS语言介绍与组件方式运用
从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是…...
音频播放软件Foobar2000 mac特点介绍
Foobar2000 mac是一款高度可定制的音频播放器,适用于Windows平台。它支持各种音频格式,包括MP3、FLAC、AAC、WMA等,同时也支持各种音频插件和效果器,可以提供更好的音质和用户体验。 Foobar2000 mac软件特点 1. 高度可定制&#…...