计算机图形学 3D 渲染 笔记(二)

news2024/9/22 11:28:06

一、阴影

  • 判断一个点是否被遮住,可以从该点像光源方向发射射线(P + tL),若射线被与物体发生相交,则说明它在阴影中。而这个物体由于要在 P 和 光源之间,在方向光场景下, t 的取值范围是 0 < t < +∞(因为光源无限远),而在点光下, t 的取值范围是 0 < t < 1

二、光栅化三角形

光追的简单性的代价是性能。而光栅化渲染模型是追求性能,而不是数学纯度。它的思维方式和光追相反。

  • 光追:思考画布上的每个像素,场景中的哪个物体在这里是可见的?

  • 光栅化:思考场景中的物体,在画布上的哪个像素这个物体是可见的?

  • 绘制任意斜率的直线
    当线趋于水平时(abs(dx) > abs(dy))使用 y = f(x) ,确保能画出水平线
    当线趋于垂直时(abs(dy) > abs(dx))使用 x = f(y) ,确保能画出垂直线

  • 线性插值函数
    是基于绘制任意斜率中提取的公共部分,为 Interpolate() ,它计算两点之间线段上的点的 x 或 y 值,放置到一个数组中。当线趋于水平时,使用 Interpolate(x0,y0, x1,y1) 返回这些值是 y(因变量),当线趋于垂直时,使用Interpolate(y0,x0, y1,x1) 返回的这些值是 x
    这并不是最好的算法,目前比较好的直线算法是布兰森汉姆算法

  • 三角形的绘制方式
    给定三角形, 找出长边和短边,通过长边和两条短边的 x 坐标并集,找出左边的边和右边的边,自底向上从左边的点绘制到右边的点

  • 三角形的边缘着色
    三角形颜色基色为 C,已知三个顶点的颜色强度为 h(取值范围为 [0,1],0表示黑色,1表示原色),那么每个点的颜色为 Ch = (Rc h, Gc h, Bc h)
    其次,边缘两点之间的点的颜色,可以用 h = f(P) 来计算,但是我们不知道它们的关系,所以可以先悬着一条兼容的函数,如下面的线性函数。
    和三角形绘制的方式一样,我们通过线性插值函数,来计算每条边的上 h 的取值范围:
    h01 = Interpolate(y0,h0, y1,h1) h12 = Interpolate(y1,h1, y2,h2) h02 = Interpolate(y0,h0, y2,h2)
    然后跟随 x 取值找出每个水平线上的最左值和最右值
    在这里插入图片描述

  • 三角形内部着色
    在获取到条水平线上的 hl 和 hr 之后,我们可以通过 xl 和 xr,来使用线性插值器计算这个线段上每个点的 h 值,这样就可以获取到每个像素的颜色了

三、 透视投影

  • 查找视口上的 P’ 点
    通过右视,可以用相似三角形的方法,确定 P'y = Py·d / Pz
    通过俯视,确定 P'z = Px·d / Pz
    在这里插入图片描述在这里插入图片描述
  • 透视投影方程
    将上述整合在一起,给定场景中的一个点 P 以及相机位置和视口的设置,我们可以计算 P 在视口上的投影,我们称之为 P’,那么 P’ 的坐标就是 (Px·d/Pz, Py·d/Pz, d),在前面章节中学习了 画布 - 视口转化方程,这里需要反过来,编程 视口 - 画布转化方程,因此视口上 P’ 对应的 画布坐标为:
// Cw、Ch 为画布长宽, Vw Vh 为视口长宽
Cx = P'x · Cw / Vw
Cy = P'y · Ch / Vh
  • 表示一个立方体
    一个立方体可以看出是 8 个顶点,组成的 12 个三角形,因此可以使用绘制三角形的方式来绘制一个立方体。从而实现二维到三维的转化
  • 模型变换
    可以使用三个元素来定义模型变化,分别是:缩放旋转平移,无论是先平移后旋转,还是旋转后平移,都可以达成一样的效果,而在计算中,我们采用:先缩放,后旋转,最后平移 来计算模型最后的形态。
    在固定场景中旋转和平移相机,与固定相机而旋转和平移场景是没有区别的。但是如如果固定相机,并指向 Z+,我们的透视投影方程就不用做出任何修改。这种坐标系也被称为相机空间。
    假设相机也附加了变化,包括平移、旋转,为了从相机的视野去渲染场景,我们需要对场景中的每个顶点应用相反的变化,计算如下:
Vtranslated = Vscene - camera.translation    // 世界平移程度(每个坐标的移动距离) = 每个场景的坐标 - 相机的平移距离
Vcam_space = inverse(camera.roation) · Vtranslated    // 相机的位置 = 旋转后平移位置, 这里的旋转角度是相机本身的旋转角度的相反数
Vprojected = perspective_projection(Vcam_space)    // 此时可以使用投影透视方程,算出场景中每个物体在平面上的坐标
  • 变换矩阵
    现在考虑在移动相机时,模型空间中的顶点 Vmodel 所发生的事情,直到它被投影到画布点 (cx, cy)。我们首先应用模型从模型空间到世界空间:
Vmodel_scaled = instance.scale · Vmodel  // 模型缩放后的模型 = 实例的缩放因子 * 模型原始大小
Vmodel_roated = instance.roation · Vmodel_scaled  // 模型旋转后的模型 = 实例的旋转因子 * 模型缩放后的模型
Vworld = Vmodel_rotated + instance.translation   // 世界空间的每个点 = 模型旋转后的模型 + 实例的平移距离

然后应用相机变化,从世界空间变换到相机空间:

Vtranslated = Vworld - camera.translation                  // 世界平移坐标 = 世界原位置 - 相机移动位置
Vcamera = inverse(camera.roation) · Vtranslated      // 相机位置 = 相机反方向旋转然后平移 

接下来,应用透视方程获得视口坐标:

vx = Vcamera.x · d / Vcamera.z
vy = Vcamera.y · d / Vcamera.z

最后将视口坐标映射到画布坐标:

cx = vx · cw / vw
cy = vy ·  ch / vh

下面来简化这个方程,函数的输入是场景中的任意顶点,返回的是变化之后的顶点位置。设 Ct、Cr 为相机平移函数和旋转函数,IR、IS、IT 为模型实例的旋转函数、缩放函数、平移函数,P 为透视投影函数,M为视口-画布转换函数。V 表示原始顶点位置,V’ 表示画布上的坐标,我们可以使用下面这样表示以上所有方程:

V' = M(P(CR%^-1(CT^-1(IT(IR(IS(V)))))))        // 新顶点坐标 = 模型上的原始坐标被缩放、旋转、平移后,再经过被相机自身平移、缩放,被投影到视口上,再转化到画布上
F = M · P ·CR^-1 · CT^-1 · IT ·IR · IS     // 定义函数
V' = F(V)
  • 齐次坐标
    由于 A = (x, y, z) 可以表示为一个点(笛卡尔坐标系),也可以表示为一个向量,因此为了更好的区分它们,我们引入 w 值,w = 0 时表示它为向量,w = 1时表示它为点, 我们称 A=(x,y, z, w) 为齐次坐标 。 处理齐次坐标与处理向量是一致的,例如:
(8, 4, 2, 1) - (3, 2, 1, 1) = (5, 2, 1, 0)

当 w 既不为0 也不为1时,它依然表示点,而 w 则是坐标个 w 值之间的比率,例如 (1,2,3,1) 和 (2,4,6,2) 表示的是同一个点,我们可以使用下面公式,将齐次坐标转化为笛卡尔坐标

(x, y , z , w) = (x/w, y/w, z/w, 1) = (x/w, y/w, z/w)

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

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

相关文章

vue3+vite+Ts 基于Antv/x6 绘制流程图

需求效果&#xff1a; 需求&#xff1a; 实现一个流程图&#xff0c;双击可对相应的组件进行一些功能操作&#xff1b; 工具栈&#xff1a; 这里使用antv/x6&#xff0c; 基于vue3vitets进行开发 官网地址&#xff1a; https://x6.antv.antgroup.com/examples/showcase/pra…

港联证券|dmi指标的用法和实战技巧?

DMI指标是一种技术分析工具&#xff0c;可用于评估股票、期货和外汇市场的趋势强度。DMI指标由三条线组成&#xff0c;分别是DI&#xff08;上升方向指标&#xff09;、-DI&#xff08;下降方向指标&#xff09;和ADX&#xff08;平均趋向指数&#xff09;。在使用DMI指标之前&…

Unity DOTS纯ECS实现虚拟摇杆Joystick控制角色移动

上篇已经实现了ECS框架下的IBeginDragHandler、IDragHandler、IEndDragHandler这几个拖动事件&#xff0c;使得可以任意给ECS框架下的UI(2D entity)响应拖动事件。本篇分享下在前篇实现的功能的基础上再实现一个常用的摇杆控制角色移动的功能。 需要注意的一点&#xff0c;目前…

[数据分析与可视化] 基于matplotlib和plottable库绘制精美表格

plottable是一个Python库&#xff0c;用于在matplotlib中绘制精美定制的图形表格。plottable的官方仓库地址为&#xff1a;plottable。本文主要参考其官方文档&#xff0c;plottable的官方文档地址为&#xff1a;plottable-doc。plottable安装命令如下&#xff1a; pip install…

猿人web学刷题18

1.第十八题 jsvmp - 猿人学 问题: 1.第一页请求正常能返回数据 2.第二页开始之后出现{"error": "Unexpected token/Validation failed"} 分析&#xff1a; 1.第二页开始&#xff0c;有带加密参数&#xff0c;直接重发请求无果&#xff0c;应该带了时间戳…

尚硅谷Docker实战教程-笔记11【高级篇,Docker网络】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

盛格塾暑期公益课程《学活LINUX》

学习LINUX有很多种方法&#xff0c;本系列课程以动手试验为主&#xff0c;取一个活的LINUX系统&#xff08;GDK8&#xff09;作为目标&#xff0c;使用内核调试器&#xff08;挥码枪&#xff09;将其中断到调试器&#xff0c;在调试器的帮助下&#xff0c;观察调用过程、执行现…

【1++的Linux】之基础开发工具

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的Linux】 文章目录 一&#xff0c;Linux软件包管理管理器二&#xff0c;Linux编辑器--vim2.1 什么是vim2.2 vim的基本操作 三&#xff0c;gcc的使用四&#xff0c;gdb的使用五&#xff0c;项目…

课时7:Trustzone基础知识

快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:Secureboot从入门到精通-[目录] 👈👈👈目录 Trustzone安全扩展双系统架构Trustone架构多方位支持的安全

探索Gradio库中的Textbox模块及其强大功能

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

作用域、垃圾回收机制、闭包、构造函数

作用域 作用域规定了变量能够被访问的 ‘范围’&#xff0c;离开了这个范围变量便不能被访问 分为&#xff1a; 局部作用域 函数作用域块级作用域 let/const 全局作用域 作用域链 嵌套关系的作用域串联起来形成了作用域链 作用:作用域链本质上是底层的变量的查找机制 函…

简写MKL库windows安装以及python如何调用dll库

MKL安装: 最新MKL库下载地址 Donwload: Accelerate Fast Math with Intel oneAPI Math Kernel Library 64位以及32位我直接都安装了 之后配置各种包含目录以及环境变量&#xff1a;网上有很多配置vs的配置教程&#xff0c;这里就不贴了。 &#xff08;ps: 2023 在vs2019上&a…

nodejs高级编程-核心模块

一、path 1 获取路径中的基础名称 const path require(path)// console.log(__filename) // /Users/liuchongyang/Desktop/分享/网页读取本地文件/node.js// 1 获取路径中的基础名称 /*** 01 返回的就是接收路径当中的最后一部分 * 02 第二个参数表示扩展名&#xff0c;如果…

手把手教-单片机stm32基于w25q128使用文件系统

一、开发测试环境 ①野火stm32f407开发板 ②rtthread操作系统 W25Q128的电路原理图&#xff1a; 二、开发步骤 ①使能spi驱动。 ②使能spi bus/device 驱动&#xff0c;选择sfud驱动。 ③开启dfs功能&#xff0c;选择elm文件系统。 ④保存&#xff0c;重新生成工程。 ⑤下载到…

VueCli 脚手架使用

VueCli 脚手架 到目前为止&#xff0c;已经会了Vue基本使用&#xff08;去创建vue实例&#xff0c;创建之后再去挂载&#xff0c;挂载之后就去使用各种功能&#xff0c;挂载之后就可以使用其各种功能&#xff0c;data methods compute 以及各个生命周期&#xff0c;常用的属性以…

779. 最长公共字符串后缀

题面&#xff1a; 给出若干个字符串&#xff0c;输出这些字符串的最长公共后缀。 输入格式 由若干组输入组成。 每组输入的第一行是一个整数 NN。 NN 为 00 时表示输入结束&#xff0c;否则后面会继续有 NN 行输入&#xff0c;每行是一个字符串&#xff08;字符串内不含空白符&…

Redis深入 —— 持久化和事务

前言 最近的学习中&#xff0c;荔枝深入了解了Redis的持久化、Redis事务相关的知识点并整理相应的学习笔记&#xff0c;在这篇文章中荔枝也主要梳理了相应的笔记和基本知识&#xff0c;小伙伴们如果需要的话可以看看哈。 文章目录 前言 一、Redis持久化 1.1 RDB 1.1.1 Redi…

掌握驱动之道:L298N模块多方式驱动电机的优劣分析

L298N模块是一种常用的直流电机驱动模块&#xff0c;它可以通过控制输入端口来实现对电机的速度和方向的控制。L298N模块有3个输入端口&#xff1a;IN1、IN2和EN。 方法一&#xff1a;使用高级定时器输出通道和互补输出通道控制电机 将模块的IN1和IN2分别连接到STM32高级定时器…

Python GUI编程利器:Tkinker中的事件处理(11)

​ 小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日目标 学习下事件处理的相关知识点&#xff1a; 事件处理四要素 事件序列 事件绑定 今天要实现如下效果&#xff1…

Java在Excel中进行数据分析

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前一段时间淘宝出了一个“淘宝人生”的模块&#xff0c;可以看从注册淘宝账号至今的消…