图形学初识--屏幕空间变换

2024-06-01 18:12

本文主要是介绍图形学初识--屏幕空间变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 正文
    • 为什么需要屏幕空间变换?
    • 什么是屏幕空间变换?
    • 屏幕空间变换矩阵如何推导?
      • 问题描述
      • 步骤描述
  • 结尾:喜欢的小伙伴点点关注+赞哦!

前言

前面章节主要讲解了视图变换和投影变换,此时距离在屏幕空间显示也就只差一步之遥了,只需要将NDC坐标转换为屏幕空间坐标即可!有了前面一些章节的学习,相信大家对于本章节的学习还是很容易的!

正文

为什么需要屏幕空间变换?

因为经过了视图变换和投影变换后,咱们已经将所有的顶点坐标转换成了NDC坐标,也就是x/y/z的范围都在 [ − 1 , 1 ] [-1,1] [1,1] 的坐标,但是正常咱们得电脑屏幕的XY坐标范围一般都是 [ 0 , w i d t h − 1 ] × [ 0 , h e i g h t − 1 ] [0,width-1] \times [0, height-1] [0,width1]×[0,height1] ,所以咱们需要屏幕空间变换!

什么是屏幕空间变换?

本质上和之前的视图变换、投影变换并无不同,就是一个矩阵罢了!

屏幕空间变换矩阵如何推导?

问题描述

将x坐标由 [ − 1 , 1 ] [-1,1] [1,1] 变换为 $ [0,screen_width - 1]$ ,将y坐标由 [ − 1 , 1 ] [-1,1] [1,1] 变换为 $ [0,screen_height - 1]$ ,将z坐标由 [ − 1 , 1 ] [-1,1] [1,1] 变换为 $ [0,1]$​.

如下图所示:

在这里插入图片描述

步骤描述

步骤1:将xyz坐标变换到 [ 0 , 1 ] [0,1] [0,1] 的范围

步骤2:将xy坐标缩放至 [ 0 , s c r e e n w i d t h − 1 ] × [ 0 , s c r e e n h e i g h t − 1 ] [0, screen_width - 1] \times [0, screen_height - 1] [0,screenwidth1]×[0,screenheight1]

咱们先思考下步骤1如何实现呢?当前的xyz坐标范围为 [ − 1 , 1 ] [-1,1] [1,1] ,目标的坐标范围为 [ 0 , 1 ] [0,1] [0,1] ,如何做呢?

这时候其实咱们分两步:

第一步:将 [ − 1 , 1 ] [-1,1] [1,1] 缩放至 [ − 0.5 , 0.5 ] [-0.5,0.5] [0.5,0.5] 的范围。

第二步:将 [ − 0.5 , 0.5 ] [-0.5,0.5] [0.5,0.5] 沿着对应轴轴方向移动0.5单位即可。

于是咱们分别得到缩放矩阵和平移矩阵如下:
S = [ 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 1 ] S = \begin{bmatrix} 0.5&0&0&0\\ 0&0.5&0&0\\ 0&0&0.5&0\\ 0&0&0&1\\ \end{bmatrix} S= 0.500000.500000.500001

T = [ 0 0 0 0.5 0 0 0 0.5 0 0 0 0.5 0 0 0 1 ] T = \begin{bmatrix} 0&0&0&0.5\\ 0&0&0&0.5\\ 0&0&0&0.5\\ 0&0&0&1\\ \end{bmatrix} T= 0000000000000.50.50.51

于是咱们只需要将两者相乘,即可获得相应的结果:
M 1 = T ∗ S = [ 0.5 0 0 0.5 0 0.5 0 0.5 0 0 0.5 0.5 0 0 0 1 ] M_1 = T * S = \begin{bmatrix} 0.5&0&0&0.5\\ 0&0.5&0&0.5\\ 0&0&0.5&0.5\\ 0&0&0&1\\ \end{bmatrix} M1=TS= 0.500000.500000.500.50.50.51

然后咱们思考下步骤二,当前的xy坐标范围为: [ 0 , 1 ] [0,1] [0,1] ,目标范围为 $[0,screen_width-1] 和 [0,screen_height-1] $

这个问题也就只是个xy轴的缩放问题而已,很容易得到以下缩放矩阵:
M 2 = [ s c r e e n _ w i d t h 0 0 0 0 s c r e e n _ h e i g h t 0 0 0 0 1 0 0 0 0 1 ] M_2 = \begin{bmatrix} screen\_width&0&0&0\\ 0&screen\_height&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix} M2= screen_width0000screen_height0000100001

然后咱们将步骤一的结果和步骤二的结果结合起来即可得到最终的屏幕空间变换矩阵,如下:
M s c r e e n = M 2 ∗ M 1 = M 2 = [ 0.5 ∗ s c r e e n _ w i d t h 0 0 0.5 ∗ s c r e e n _ w i d t h 0 0.5 ∗ s c r e e n _ h e i g h t 0 0.5 ∗ s c r e e n _ h e i g h t 0 0 0.5 0.5 0 0 0 1 ] M_{screen}= M_2 * M_1 = M_2 = \begin{bmatrix} 0.5*screen\_width&0&0&0.5*screen\_width\\ 0&0.5*screen\_height&0&0.5*screen\_height\\ 0&0&0.5&0.5\\ 0&0&0&1\\ \end{bmatrix} Mscreen=M2M1=M2= 0.5screen_width00000.5screen_height00000.500.5screen_width0.5screen_height0.51

于是大功告成啦!咱们成功的将NDC坐标转换成了屏幕空间坐标!

结尾:喜欢的小伙伴点点关注+赞哦!

你们的点赞就是我创作的最大动力!希望对各位小伙伴能够有所帮助哦,永远在学习的道路上伴你而行, 我是航火火,火一般的男人!

这篇关于图形学初识--屏幕空间变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Linux操作系统 初识

在认识操作系统之前,我们首先来了解一下计算机的发展: 计算机的发展 世界上第一台计算机名叫埃尼阿克,诞生在1945年2月14日,用于军事用途。 后来因为计算机的优势和潜力巨大,计算机开始飞速发展,并产生了一个当时一直有效的定律:摩尔定律--当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 那么相应的,计算机就会变得越来越快,越来越小型化。

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

【高等代数笔记】线性空间(一到四)

3. 线性空间 令 K n : = { ( a 1 , a 2 , . . . , a n ) ∣ a i ∈ K , i = 1 , 2 , . . . , n } \textbf{K}^{n}:=\{(a_{1},a_{2},...,a_{n})|a_{i}\in\textbf{K},i=1,2,...,n\} Kn:={(a1​,a2​,...,an​)∣ai​∈K,i=1,2,...,n

Weex入门教程之4,获取当前全局环境变量和配置信息(屏幕高度、宽度等)

$getConfig() 获取当前全局环境变量和配置信息。 Returns: config (object): 配置对象;bundleUrl (string): bundle 的 url;debug (boolean): 是否是调试模式;env (object): 环境对象; weexVersion (string): Weex sdk 版本;appName (string): 应用名字;

一款支持同一个屏幕界面同时播放多个视频的视频播放软件

GridPlayer 是一款基于 VLC 的免费开源跨平台多视频同步播放工具,支持在一块屏幕上同时播放多个视频。其主要功能包括: 多视频播放:用户可以在一个窗口中同时播放任意数量的视频,数量仅受硬件性能限制。支持多种格式和流媒体:GridPlayer 支持所有由 VLC 支持的视频格式以及流媒体 URL(如 m3u8 链接)。自定义网格布局:用户可以配置播放器的网格布局,以适应不同的观看需求。硬

docker学习系列(一)初识docker

在第一版本上线之后公司,我们决定将之前使用的开源api文档项目转移到本公司的服务器之上,之前用的是showdoc,showdoc利用的是php技术,作为java程序员表示需要快速部署php环境以及apach容器都需要时间,所以采用第二种方法,即利用docker进行快速部署(虽然学习成本也不比php少)。 一、docker简介 docker的官网是https://www.docker.com,

win7系统中C盘空间缩水的有效处理方法

一、深度剖析和完美解决   1、 休眠文件 hiberfil.sys :   该文件在C盘根目录为隐藏的系统文件,隐藏的这个hiberfil.sys文件大小正好和自己的物理内存是一致的,当你让电脑进入休眠状态时,Windows 7在关闭系统前将所有的内存内容写入Hiberfil.sys文件。   而后,当你重新打开电脑,操作系统使用Hiberfil.sys把所有信息放回内存,电脑

求空间直线与平面的交点

若直线不与平面平行,将存在交点。如下图所示,已知直线L过点m(m1,m2,m3),且方向向量为VL(v1,v2,v3),平面P过点n(n1,n2,n3),且法线方向向量为VP(vp1,vp2,vp3),求得直线与平面的交点O的坐标(x,y,z): 将直线方程写成参数方程形式,即有: x = m1+ v1 * t y = m2+ v2 * t

[Linux]:环境变量与进程地址空间

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 环境变量 1.1 概念 **环境变量(environment variables)**一般是指在操作系统中用来指定操作系统运行环境的一些参数,具有全局属性,可以被子继承继承下去。 如:我们在编写C/C++代码的时,在链接的时候,我们并不知

【编程底层原理】方法区、永久代和元空间之间的关系

Java虚拟机(JVM)中的内存布局经历了几个版本的变更,其中方法区、永久代和元空间是这些变更中的关键概念。以下是它们之间的关系: 一、方法区: 1、方法区是JVM规范中定义的一个概念,它用于存储类信息、常量、静态变量、即时编译器编译后的代码等数据。 3、它是JVM运行时数据区的一部分,与堆内存一样,是所有线程共享的内存区域。 二、永久代(PermGen): 1、在Java SE 7之前,