Unity中Shader裁剪空间推导(透视相机到裁剪空间的转化矩阵)

文章目录

  • 前言
  • 一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化
    • 1、观察空间(右手坐标系、透视相机)
    • 2、裁剪空间(左手坐标系、且转化为了齐次坐标)
    • 3、屏幕空间(把裁剪坐标归一化设置)
    • 4、从观察空间到裁剪空间
    • 5、从裁剪空间到屏幕空间后
  • 二、透视相机的参数推导
    • 1、从XoY平面,求出X~v~从观察空间到裁剪空间的坐标投影 X~p~
    • 2、从YoZ平面,求出Y~v~从观察空间到裁剪空间的坐标投影 Y~p~
  • 三、把投影到近裁剪面的坐标 归一化设置
    • 1、求归一化设置后的 x~n~
    • 2、求归一化设置后的 y~n~
    • 3、得到最后化简的公式
  • 四、构建转化矩阵
    • 1、在OpenGL[-1,1]下:
    • 2、在DirectX[1,0]下:
    • 3、把A、B代入矩阵得


前言

我们把顶点坐标信息转化为裁剪空间。有可能使用到正交相机信息 或 透视相机。我们在这篇文章中,推导一下透视相机视图空间下的坐标转化到裁剪空间的矩阵。

在这里插入图片描述


一、简单看一下 观察空间—>裁剪空间—>屏幕空间 的转化

在这里插入图片描述

1、观察空间(右手坐标系、透视相机)

在这里插入图片描述

2、裁剪空间(左手坐标系、且转化为了齐次坐标)

在这里插入图片描述

3、屏幕空间(把裁剪坐标归一化设置)

在这里插入图片描述

4、从观察空间到裁剪空间

用透视投影矩阵先转化到裁剪空间
然后,在转化为齐次坐标

5、从裁剪空间到屏幕空间后

− 1 ≤ x c w ≤ 1 -1 \leq \frac{x_c}{w}\leq1 1wxc1

− w ≤ x c ≤ w -w \leq x_c\leq w wxcw


二、透视相机的参数推导

在这里插入图片描述

  • 我们对于远裁剪面只是已知 f,其他参数都是未知

1、从XoY平面,求出Xv从观察空间到裁剪空间的坐标投影 Xp

在这里插入图片描述

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知: ( x v , y v , z v ) 、 − n (x_v,y_v,z_v) 、 -n (xv,yv,zv)n
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知: ( x p , y p , z p ) (x_p,y_p,z_p) (xp,yp,zp)
  • 我们在 XoZ平面上,能求的就是 xp
    求: x p x_p xp

z p = − n z_p = -n zp=n

y p 在 X o Z 平面下,无法计算 y_p 在XoZ平面下,无法计算 ypXoZ平面下,无法计算

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

x p x v = − n z v \frac{x_p}{x_v} = \frac{-n}{z_v} xvxp=zvn

x p = − n z v x v x_p = \frac{-n}{z_v} x_v xp=zvnxv

P = ( − n z v x v , 未知 , − n ) P = (\frac{-n}{z_v}x_v,未知,-n) P=(zvnxv,未知,n)

2、从YoZ平面,求出Yv从观察空间到裁剪空间的坐标投影 Yp

在这里插入图片描述

  • 点 V 是观察空间下的模型顶点,xyz是已知的
    已知: ( x v , y v , z v ) 、 − n (x_v,y_v,z_v) 、 -n (xv,yv,zv)n
  • 点P是该点在近裁剪面上的投影点,xyz是未知的
    未知: ( x p , y p , z p ) (x_p,y_p,z_p) (xp,yp,zp)
  • 我们在 YoZ平面上,能求的就是 yp
    求: y p y_p yp

z p = − n z_p = -n zp=n

x p 在 X o Z 平面下,无法计算 x_p 在XoZ平面下,无法计算 xpXoZ平面下,无法计算

  • v点向Z轴做垂线,原点连接v点,围成的两个三角形相似,可得:

y p y v = − n z v \frac{y_p}{y_v} = \frac{-n}{z_v} yvyp=zvn

y p = − n z v y v y_p = \frac{-n}{z_v} y_v yp=zvnyv

P = ( − n z v x v , − n z v y v , − n ) P = (\frac{-n}{z_v}x_v,\frac{-n}{z_v} y_v,-n) P=(zvnxv,zvnyv,n)


三、把投影到近裁剪面的坐标 归一化设置

P = ( − n z v x v , − n z v y v , − n ) P = (\frac{-n}{z_v}x_v,\frac{-n}{z_v} y_v,-n) P=(zvnxv,zvnyv,n)

化到[-1,1]之间
具体参考Unity中Shader裁剪空间推导(正交相机到裁剪空间的转化矩阵)

1、求归一化设置后的 xn

  • l ≤ x ≤ r l \leq x \leq r lxr 化为: − 1 ≤ 2 x w ≤ 1 -1 \leq \frac{2x}{w} \leq 1 1w2x1

− 1 ≤ − 2 n x v z v w ≤ 1 -1\leq \frac{-2nx_v}{z_vw}\leq 1 1zvw2nxv1

− 1 ≤ − 2 n w ⋅ x v z v ≤ 1 -1\leq \frac{-2n}{w}·\frac{x_v}{z_v}\leq 1 1w2nzvxv1

2、求归一化设置后的 yn

  • l ≤ y ≤ r l \leq y \leq r lyr 化为: − 1 ≤ 2 y h ≤ 1 -1 \leq \frac{2y}{h} \leq 1 1h2y1

− 1 ≤ − 2 n y v z v h ≤ 1 -1\leq\frac{-2ny_v}{z_vh}\leq1 1zvh2nyv1

− 1 ≤ − 2 n h ⋅ y v z v ≤ 1 -1\leq\frac{-2n}{h}·\frac{y_v}{z_v}\leq1 1h2nzvyv1

3、得到最后化简的公式

由于NDC下的坐标由透视除法而得
我们假设透视除法中的 w 为 -zv
还原到裁剪空间还需要乘以 -zv

  • X:

− 1 ≤ − 2 n w ⋅ x v z v ≤ 1 -1\leq \frac{-2n}{w}·\frac{x_v}{z_v}\leq 1 1w2nzvxv1

x n = − 2 n w x v z v x_n = \frac{-2n}{w}\frac{x_v}{z_v} xn=w2nzvxv

− x n z v = 2 n w x v -x_nz_v = \frac{2n}{w}x_v xnzv=w2nxv

  • Y:

− 1 ≤ − 2 n h ⋅ y v z v ≤ 1 -1\leq\frac{-2n}{h}·\frac{y_v}{z_v}\leq1 1h2nzvyv1

y n = − 2 n h y v z v y_n = \frac{-2n}{h}\frac{y_v}{z_v} yn=h2nzvyv

− y n z v = 2 n h y v -y_n z_v= \frac{2n}{h}y_v ynzv=h2nyv

  • Z:

z n = ? z_n = ? zn=?

− z n z v = − z v ? -z_nz_v = -z_v? znzv=zv?

  • W:

w = 1 w = 1 w=1

− w n z v = − z v -w_nz_v = -z_v wnzv=zv


四、构建转化矩阵

裁剪空间下的点 = 观察空间下的基向量 在 裁剪空间下的矩阵 * 点在观察空间下的坐标

P c = [ V c ] ⋅ P v P_c = [V_c]·P_v Pc=[Vc]Pv

P c = [ C v ] − 1 ⋅ P v P_c = [C_v]^{-1}·P_v Pc=[Cv]1Pv

P c = [ C v ] T ⋅ P v P_c = [C_v]^{T}·P_v Pc=[Cv]TPv

  • − x n z v = 2 n w x v -x_nz_v = \frac{2n}{w}x_v xnzv=w2nxv
  • − y n z v = 2 n h y v -y_n z_v= \frac{2n}{h}y_v ynzv=h2nyv
  • − z n z v = − z v ? -z_nz_v = -z_v? znzv=zv?
  • − w n z v = − z v -w_nz_v = -z_v wnzv=zv

[ 2 v w 0 ? ? 0 2 n h ? ? 0 0 ? ? 0 0 ? ? ] T = [ 2 v w 0 0 0 0 2 n h 0 0 ? ? ? ? ? ? ? ? ] \begin{bmatrix} \frac{2v}{w} & 0 & ? &?\\ 0 & \frac{2n}{h} & ? &?\\ 0 & 0 & ? &?\\ 0 & 0 & ? & ?\\ \end{bmatrix}^T =\begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ ? & ? & ? &?\\ ? & ? & ? & ?\\ \end{bmatrix} w2v0000h2n00???????? T= w2v0??0h2n??00??00??

[ 2 v w 0 0 0 0 2 n h 0 0 ? ? ? ? ? ? ? ? ] ⋅ [ x v y v z v 1 ] = ( − x n z v , − y n z v , − z n z v , − w n z v ) \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ ? & ? & ? &?\\ ? & ? & ? & ?\\ \end{bmatrix} · \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1\\ \end{bmatrix} = (-x_nz_v,-y_nz_v,-z_nz_v,-w_nz_v) w2v0??0h2n??00??00?? xvyvzv1 =(xnzv,ynzv,znzv,wnzv)

最后一行由于相乘结果为1可以得出,把最后未知部分设为A,B
[ 2 v w 0 0 0 0 2 n h 0 0 0 0 A B 0 0 − 1 0 ] ⋅ [ x v y v z v 1 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & A &B\\ 0 & 0 & -1 & 0\\ \end{bmatrix} · \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1\\ \end{bmatrix} w2v0000h2n0000A100B0 xvyvzv1

z c = A z v + B z_c = Az_v+B zc=Azv+B

− z n z v = − z v -z_nz_v = -z_v znzv=zv

z c − z v = A z v + B − z v \frac{z_c}{-z_v} = \frac{Az_v+B}{-z_v} zvzc=zvAzv+B

z n = A z v + B − z v z_n = \frac{Az_v+B}{-z_v} zn=zvAzv+B

1、在OpenGL[-1,1]下:

z n = A z v + B − z v z_n = \frac{Az_v+B}{-z_v} zn=zvAzv+B

{ z v = − n , z n = − 1 z v = − f , z n = 1 \begin{cases} z_v = -n,z_n=-1 \\ z_v = -f,z_n = 1 \end{cases} {zv=n,zn=1zv=f,zn=1

{ − 1 = − A n + B n 1 = − A f + B f \begin{cases} -1 = \frac{-An+B}{n}\\ 1 = \frac{-Af + B}{f} \end{cases} {1=nAn+B1=fAf+B

{ − n = − A n + B f = − A f + B \begin{cases} -n = -An+B\\ f = -Af + B \end{cases} {n=An+Bf=Af+B

B = A n − n B = An - n B=Ann

f = − A f + A n − n f = -Af +An-n f=Af+Ann

f + n = A ( n − f ) f + n= A(n-f) f+n=A(nf)

A = n + f n − f A = \frac{n+f}{n-f} A=nfn+f

B = n + f n − f n − n B = \frac{n+f}{n-f}n-n B=nfn+fnn

B = n 2 + f n n − f n 2 − n f n − f B = \frac{n^2 + fn}{n-f}\frac{n^2-nf}{n-f} B=nfn2+fnnfn2nf

B = 2 n f n − f B = \frac{2nf}{n-f} B=nf2nf

2、在DirectX[1,0]下:

z n = A z v + B − z v z_n = \frac{Az_v+B}{-z_v} zn=zvAzv+B

{ z v = − n , z n = 1 z v = − f , z n = 0 \begin{cases} z_v = -n,z_n=1 \\ z_v = -f,z_n = 0 \end{cases} {zv=n,zn=1zv=f,zn=0

{ 1 = − A n + B n 0 = − A f + B f \begin{cases} 1 = \frac{-An+B}{n}\\ 0 = \frac{-Af+B}{f} \end{cases} {1=nAn+B0=fAf+B

{ n = − A n + B 0 = − A f + B \begin{cases} n = -An+B\\ 0 = -Af+B \end{cases} {n=An+B0=Af+B

B = A f B = Af B=Af

n = − A n + A f n = -An+Af n=An+Af

n = A ( f − n ) n = A(f-n) n=A(fn)

A = n f − n A =\frac{n}{f-n} A=fnn

B = n f f − n B = \frac{nf}{f-n} B=fnnf

3、把A、B代入矩阵得

  • OpenGL
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n + f n − f 2 n f n − f 0 0 − 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n+f}{n-f} &\frac{2nf}{n-f}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} w2v0000h2n0000nfn+f100nf2nf0
  • DirectX
    [ 2 v w 0 0 0 0 2 n h 0 0 0 0 n f − n n f f − n 0 0 − 1 0 ] \begin{bmatrix} \frac{2v}{w} & 0 & 0 & 0 \\ 0 & \frac{2n}{h} & 0 &0\\ 0 & 0 & \frac{n}{f-n} &\frac{nf}{f-n}\\ 0 & 0 & -1 & 0\\ \end{bmatrix} w2v0000h2n0000fnn100fnnf0

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

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

相关文章

Linux文件编程

目录 1、Linux系统提供的文件编程API 1.1打开文件:open 1.2创建文件creat函数 1.3写入文件write函数 1.4读取文件read函数 1.5文件光标位置lseek函数 2、另外一组文件编程API 2.1文件打开函数fopen 2.2读文件函数fread 2.3写文件函数fwrite 2.4文件光标位…

github鉴权失败

问题: 如上图所示 git push 时发生了报错,鉴权失败; 解决方案 Settings->Developer settings->Personal access tokens->Generate new token。创建新的访问密钥,勾选repo栏,选择有效期,为密钥命…

HarmonyOS4.0系统性深入开发08服务卡片架构

服务卡片概述 服务卡片(以下简称“卡片”)是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用(当前卡片使用方只支持系统应用,如桌…

小型内衣洗衣机什么牌子好?口碑好的小型洗衣机

想必大家都知道,我们的内衣裤、袜子这些衣物对卫生方面的要求是比较的高,毕竟是贴身的衣物,因此是要分开清洗的,而不能够跟我们其他的大件衣服一起放入到大型洗衣机里进行混洗,很多就选择了分开单独的手洗,…

快速上手:Docker环境下的WordPress安装全攻略

在这篇文章中我会手把手地教你在Linux环境下使用Docker安装WordPress及相关应用。最终,你将会拥有一个安全、支持https的网站。别犹豫啦,跟着我一块儿搞起来吧! 一、登录服务器 在之前的文章中有提到如何使用ssh命令登录到我们之前在AWS申请…

嵌入式SOC之通用图像处理之OSD文字信息叠加的相关实践记录

机缘巧合 机缘巧合下, 在爱芯元智的xx开发板下进行sdk的开发.由于开发板目前我拿到是当前最新的一版(估计是样品),暂不公开开发板具体型号信息.以下简称板子 .很多优秀的芯片厂商,都会提供与开发板配套的完善的软件以及完善的技术支持(FAE),突然觉得爱芯…

Kubernetes 的用法和解析(K8S 日志方案) -- 8

一、统一日志管理的整体方案 通过应用和系统日志可以了解Kubernetes集群内所发生的事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分的应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被设计成支持某种日志机制。 对…

android studio 将含有jni c++ 的library项目封装成jar并调用

请参考博客:android studio 4.1.1 将library项目封装成aar 并调用_android studio 4.1 aar release-CSDN博客 一 . 简单叙述 android studio 中可以创建Module 的两种属性,可以在build.gradle 中查看: 1. application属性:可以独…

前后端分离nodejs+vue医院预约挂号系统6nrhh

医院预约挂号系统主要有管理员、用户和医生三个功能模块。以下将对这三个功能的作用进行详细的剖析。 运行软件:vscode 前端nodejsvueElementUi 语言 node.js 框架:Express/koa 前端:Vue.js 数据库:mysql 开发软件:VScode/webstorm/hbuiderx均…

计算机视觉技术-锚框

目标检测算法通常会在输入图像中采样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边界从而更准确地预测目标的真实边界框(ground-truth bounding box)。 不同的模型使用的区域采样方法可能不同。 这里我们介…

图像分割实战-系列教程1:语义分割与实例分割概述

1、图像分割任务概述 1.1 图像分割 分割任务就是在原始图像中逐像素的找到你需要的轮廓 如图分别是(物体检测)与(图像分割)两个任务的效果对比,实际上会比检测任务要稍微麻烦一些,将图像会分为几个区域把…

学习笔记:R语言基础

文章目录 一、R语言简介二、选择R的原因三、R基本数据对象(一)向量(二)矩阵(三)数组(四)因子(五)列表(六)数据框(七&#…

uni-app condition启动模式配置

锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…

DM、Oracle、GaussDB、Kingbase8(人大金仓数据库)和HIVE给列增加注释

DM数据库给列增加注释 1、创建表 CREATE TABLE test222 ( id int NOT NULL PRIMARY KEY, name varchar(1000) DEFAULT NULL, email varchar(1000) DEFAULT NULL, phone varchar(1000) DEFAULT NULL ) 2、给列添加注释 comment on column TEST222.NAME is 这是一个列注释; 例如…

数字身份验证:跨境电商如何应对账户安全挑战?

在数字化时代,随着跨境电商的蓬勃发展,账户安全问题逐渐成为行业和消费者关注的焦点。随着网络犯罪日益猖獗,用户的数字身份安全面临着更加复杂的威胁。本文将深入探讨数字身份验证在跨境电商中的重要性,并探讨各种创新技术和策略…

Android MVC 写法

前言 Model:负责数据逻辑 View:负责视图逻辑 Controller:负责业务逻辑 持有关系: 1、View 持有 Controller 2、Controller 持有 Model 3、Model 持有 View 辅助工具:ViewBinding 执行流程:View >…

Windows系统配置pytorch环境,Jupyter notebook编辑器安装使用(深度学习本地篇)

如今现在好一点的笔记本都自带英伟达独立显卡,对于一些简单的深度学习项目,是不需要连接服务器的,甚至数据量不大的话,cpu也足够进行训练学习。我把电脑上一些以前的笔记整理一下,记录起来,方便自己35岁事业…

python/selenium/jenkins整合

1、新建python项目,专门写selenium代码,建议用pytest框架写。 2、把代码上传到代码库中。 3、环境配置: 3.1 在跑jenkins的机器上配置好python环境,需要python --version能在任何地方运行(配置好系统环境变量&#…

Idea配置热部署

Idea配置热部署 一、概念 热部署就是正在运行状态的应用,修改了他的源码之后,在不重新启动的情况下能够自动把增量内容编译并部署到服务器上,使得修改立即生效。热部署为了解决的问题有两个, 一是在开发的时候,修改代…

【Python排序算法系列】—— 选择排序

​ 🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 💫个人格言:"没有罗马,那就自己创造罗马~" 目录 选择排序 过程演示: 选择排序实现代码: 分析选择排序&#xff1a…