硬件渲染管线流程讲解,以及几种常用坐标空间概念(对象空间、世界空间、相机空间(观察空间)、NDC空间、裁剪空间、屏幕空间)

本文主要是介绍硬件渲染管线流程讲解,以及几种常用坐标空间概念(对象空间、世界空间、相机空间(观察空间)、NDC空间、裁剪空间、屏幕空间),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
对象空间

  • 每个模型都有一个其本身的坐标系,比如以它的几何中心为这个空间的坐标原点,这个模型所有顶点的位置属性都是相对于这个原点的坐标值。因此我们称这个空间为 对象空间 (局部空间)

世界空间

  • 我们要把那个模型放入我们的游戏世界中,就要对其应用一个 Model矩阵,model就是对模型做移动、旋转、缩放变换,变换后模型就以一种特定的角度、大小、位置放置在 世界空间 中了

观察空间

  • 渲染管线就是从三维空间中经过一系列计算、操作最终得到一张二维图像的过程
  • 世界空间中,现在有着相机和我们摆放的模型,为了正确的得到相机所看到的图像,但是又想计算更方便,用很小的代价把相机移动到原点并且看向-z轴,头顶着y轴,x指向相机的右方(这是几种流行图形接口所定义的),记录这种变换为 view矩阵(包含移动、旋转),接着对所有其他模型做相同的view变换。这样可以让相机和模型们都是相对静止的。相机所看到的内容,跟view变换之前的没有任何区别。而这时,在世界中,相机和模型的绝对位置和朝向其实都变了,而这种以相机为原点,相机前方为-z、头顶y、右x的坐标空间就叫做 观察空间,以上这是在101课程中听到的一种view变换的理解方法
  • 还能这样理解view变换:view矩阵是将物体从一个坐标系换到另一个坐标系的媒介。 位于世界空间的所有物体,它的坐标都是相对于世界原点而言的。做view变换之后,物体变为了以相机为原点,相机正前方向为-z轴,头顶为正y轴,右方为正x轴的坐标系来表示了

裁剪空间

  • 此时整个世界的模型都处于观察空间中,然而相机是有一定的可视范围的,这个范围我们用一个视椎体来定义。所有在视椎体内部的对象是相机可见的(可以最终显示到屏幕上),而视椎体外部则不可见(剔除)
    在这里插入图片描述
  • 为了分辨谁可见谁不可见,对观察空间的所有模型顶点,应用一个 透视投影矩阵 ,将所有的顶点变换到 裁剪空间 内。实际上在OpenGL中,矩阵计算是在顶点着色器中进行的,顶点着色器的输出gl_Position就是顶点位于裁剪空间内的坐标值,如果顶点在视椎体内,则他的xyz分量值域为[-w,w]。如果有任何一个分量绝对值超过w,则这个顶点会被裁剪不会在屏幕中出现。w分量在MVP变换前,被指定为1,经过MVP变换后,w值记录的是变换前的实际深度值

标准化设备坐标NDC空间

  • 实际上就是我们熟知的笛卡尔坐标系(x,y,z三个互相垂直的轴组成),只不过为了适配各种不同分辨率的输出设备,在NDC中规定了三个轴的取值范围为[-1,1]
  • 顶点着色器执行完后,即MVP变换完毕,紧接着P变换的后面,硬件渲染管线会自动进行 透视除法,这个阶段不可编程,顶点三个分量都除以w分量,转换到 标准化设备空间NDC-space,所有的坐标归一化,落在[-1,1]的范围内
  • 通常是硬件渲染管线中的固定功能,不可编程

屏幕空间

  • 在这个阶段,NDC坐标会被映射到屏幕坐标,通常包括将x、y坐标映射到屏幕像素坐标,此时所处的空间就叫**屏幕空间**,这个空间就是 以(0, 0)为原点,y轴上为正,x轴右为正的坐标系中。坐标范围就是显示器的分辨率大小
  • 也是硬件渲染管线中的固定功能阶段,不可编程
  • 不同的图形API所采用的屏幕空间坐标系是有差异的,比如
    • OpenGL和vulkan以屏幕左下角为原点,坐标范围是[0, width][0, height]
    • DirectX以屏幕左上角为原点,y轴向下为正,坐标范围是[0, width][0, height]
    • shaderToy网站的像素着色器,采用的是屏幕正中心为原点,坐标范围是[-width/2, width/2][-height/2, height/2]

不同的图形API和引擎可能使用不同笛卡尔坐标系约定,包括左手系右手系

在左手系中

  • x轴向右为正
  • y轴向上为正
  • z轴向外(远离观察者)为正

在右手系中

  • x轴向右为正
  • y轴向上为正
  • z轴向内(朝向观察者)为正

转换坐标系:在将模型从一个图形API迁移到另一个图形API时,通常需要应用坐标系变换来处理坐标系差异。这可能包括镜像、旋转或反转坐标轴等变换。同样的问题在屏幕空间中也许需要类似处理。

这篇关于硬件渲染管线流程讲解,以及几种常用坐标空间概念(对象空间、世界空间、相机空间(观察空间)、NDC空间、裁剪空间、屏幕空间)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

Flutter打包APK的几种方式小结

《Flutter打包APK的几种方式小结》Flutter打包不同于RN,Flutter可以在AndroidStudio里编写Flutter代码并最终打包为APK,本篇主要阐述涉及到的几种打包方式,通... 目录前言1. android原生打包APK方式2. Flutter通过原生工程打包方式3. Futte

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE