unity shader视口空间到屏幕空间各坐标的取值范围

news/2024/11/28 22:37:01/

 

模型空间->世界空间->视口空间:

比较容易理解,就是用矩阵进行缩放旋转和平移

 

视口空间(右手坐标系)-> 齐次裁剪空间(左手坐标系):

下文中的n代表near,f代表far,fov代表FOV

设视口空间坐标点为Vp = {Vx, Vy, Vz},摄像机前方的Vz为负数,裁剪空间坐标点为Cp = {Cx, Cy, Cz, Cw}

则裁剪空间的未映射坐标是:Cp = {Cx, Cy, Cz, Cw} = {Vx * n, Vy * n,  a*Vz + b, -Vz},

此时对Cp进行透视除法,得到的x,y范围是[left, right]和[bottom, top]

若对x,y从[left, right]和[bottom, top]映射到[-1, 1],则可以得到正确的裁剪坐标如下:

对此时的裁剪坐标进行透视除法,得到的x,y的范围是[-1, 1]

推导请查看:https://blog.csdn.net/zengjunjie59/article/details/109572857

变换到齐次裁剪空间后不同类型API得到的取值范围不同:

类 OpenGL 齐次裁剪空间得到的数值范围

Cx∈[-Cw, Cw],  Cy∈[-Cw, Cw],  Cz∈[-Cw, Cw],从视锥体角度看Cz∈[-near, far],  Cw = -Vz,明显,随着|Vz|的增大,|Cx|和|Cy|会随着增大(即视锥体的形状)

类 DX 齐次裁剪空间得到的数值范围

Cx∈[-Cw, Cw],  Cy∈[-Cw, Cw],  Cz∈[0, Cw], 从视锥体角度看Cz ∈ [ 0, far], Cw = -Vz某些平台下,会定义UNITY_REVERSED_Z,此时则Cz∈[Cw, 0],越靠近屏幕,Cz越接近Cw,这是为了提高近距离的深度精度,, 从视锥体角度看, Cz ∈ [near, 0](越靠近近裁切面,Cz越接近near)

详细解析:https://blog.csdn.net/acmhonor/article/details/106167261

官方文档:https://docs.unity3d.com/cn/current/Manual/SL-PlatformDifferences.html

需要注意的是:

在顶点着色器中使用UnityObjectToClipPos函数把模型空间顶点变换到裁剪空间的时候,在顶点着色器中该坐标是裁剪空间下的坐标,但是如果通过SV_POSITION语义传到片元着色器之后,该坐标会被自动变换到了屏幕坐标下,此时的x和y已经是屏幕坐标了。

 

 

Cp是齐次坐标,并且是线性相关的,即均匀更变X的时候Z也是均匀更变的(导数为常数的一次函数),可以进行线性插值,:

设Vy不变,       Vz与Vx是线性相关的(图像是一条直线)。

Cx = Vx * n,    Cx与Vx是线性相关。

Cz = a*Vz + b,  Cz与Vz是线性相关。

由于线性相关的传递性,所以Cx与Cz线性相关,y同理,所以Cp = {Cx, Cy, Cz, Cw} 裁剪坐标间可进行线性插值

例子(忽略y值,y与x同理):

需得到Cz和Cx的关系,即:Cz = f(Cx)

由于Vz和Vx是线性关系,

所以有(1)Vz = cVx + d 

(2)Cx = nVx  

(3)Cz = aVz + b   

三式联立:

Cz = f(Cx) = aVz+ b = a(cVx + d) + b = acVx + ad + b = ac(Cx/n) + ad + b = ac/nCx + ad + b

即:Cz = ac/nCx + ad + b, 所以Cz和Cx是线性关系

 

齐次裁剪空间 -> 屏幕空间:

裁剪后需要进行真正的投影,需要把视椎体投影到屏幕空间(screen space),最后会得到像素位置。

将顶点从裁剪空间投影到屏幕空间,来生成2D坐标。

第一步,需要进行齐次除法(homogeneous diision),就是把齐次坐标系中的x,y,z分量除以w,在OpenGL中这一步得到的坐标也被称为归一化的设备坐标(Normalized Device Coordinated, NDC).

在OpenGL里,x,y,z的取值范围是[-1, 1]

在DirectX里,x,y的取值范围是[-1, 1],z的取值范围是[0, 1],如果定义了UNITY_REVERSED_Z,则z的范围在[1, 0],  越靠近屏幕,z越大

深度:

即depth buffer里面的值,则是用此时的z通过线性映射到[0, 1]中,如果定义了UNITY_REVERSED_Z,则是映射到[1, 0],越靠近屏幕深度越大。

第二步,映射过程,在Unity中,屏幕左下角是(0,0),右上角是(pixelWidth,pixelHeight),由于立方体内的坐标都是[-1,1],因此映射过程就是一个缩放的过程。

齐次除法和屏幕映射可以总结为下面的公式:

 

 

此外,从裁剪空间到屏幕空间的转换是由底层帮我们完成的,如在屏幕后处理等情况中需要用到,则可调用ComputeScreenPos函数:https://blog.csdn.net/zengjunjie59/article/details/111144851

需要注意的是ComputeScreenPos如果在顶点着色器中调用,那么结果只能在顶点着色器中使用,因为经过插值之后传到片元着色器中的时候数值有错误,之所以错误是因为转换第一步中的透视除法导致NDC下的坐标Np = {Nx, Ny, Nz}中的Nx与裁剪坐标Vp中的Vz不是线性关系了。因为Nz = -b / Vz - a,设Ny不变,当投影后的Nx均匀改变的时候Vz并不是均匀改变的(导数不是常数),如果把Nx与Vz当作线性相关的进行插值求得深度Vz会是错误的,应该是一条曲线。

 

 

 

 


http://www.ppmy.cn/news/786711.html

相关文章

Matlab中空间直角坐标系中三维速度Vxyz转Ven平面速度

关于空间直角坐标系中三维速度Vxyz转Ven平面速度,需要完成连个步骤的工作:①空间直角坐标XYZ转为大地坐标BLH;② 三维速度Vxyz转Ven平面速度; 一、空间直角坐标XYZ转为大地坐标BLH 二、三维速度Vxyz转Ven平面速度 三、正式Matla…

rviz

rbx1 下载安装 一.安装 (1).克隆gmapping和amcl git clone https://github.com/ros-perception/slam_gmapping.git git clone https://github.com/ros-planning/navigation.git(2).rbx1 package 的下载 cd ~/catkin_ws/src git clone https://github.com/pirobot/rbx1.git cd…

Linux基础 | nc 网络命令,通过TCP和UDP在两台主机间建立连接传递消息、文件

nc,全名叫 netcat,它可以用来完成很多的网络功能,譬如端口扫描、建立TCP/UDP连接,数据传输、网络调试等等,因此,它也常被称为网络工具的 瑞士军刀 。 使用方式 我们可以这样来使用它: nc [-46…

计算机图形学基础:实验5 OpenGL二维几何变换

1.实验目的: 理解并掌握OpenGL二维平移、旋转、缩放变换的方法。 2.实验内容: 阅读实验原理,掌握OpenGL程序平移、旋转、缩放变换的方法。根据示范代码,完成实验作业。 3.实验原理&#xff1…

稳压二极管

一、 定义 稳压二极管,英文名称Zener diode,又叫齐纳二极管。利用PN结的反向击穿状态,其电流可在很大范围内变化而电压基本不变的现象,制成的起稳压作用的二极管。 此二极管是一种直到临界反向击穿电压前都具有很高电阻的半导体器…

[MATLAB调试笔记]时变循环诊断——[Vx(x)],[Vx(t),Vy(t),Vz(t)],[Ex(x)],[波];[Eng(t)],[Ex(k)],[Ex(x,t)],[logEx(x.t)]

静电诊断结果 电磁诊断结果 function kempo1main%*************伪随机数************%rng(default);rng(1);global flag_exitflag_exit0%*************读取参数************%prm Parameters%********renormalization*********%[prm,ren] renorm(prm);%-- initialization --[h…

【剑指offer】9. 旋转数组的最小数字(java)

文章目录 旋转数组的最小数字描述示例1示例2思路完整代码 旋转数组的最小数字 描述 有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比…

RabbitMQ系列(29)--RabbitMQ搭建Shovel

前言: Federation具备的数据转发功能类似,Shovel能够可靠、持续地从一个Broker中的队列(作为源端,即source)拉取数据并转发至另一个Broker中的交换器(作为目的端,即destination)。作为源端的队列和作为目的端的交换器可以同时位于…