精华内容
下载资源
问答
  • NDC空间中使用的是左手坐标系
    2022-02-25 09:32:22

    NDC空间中使用的是左手坐标系
    投影矩阵将右手转换为左手

    也就是说在NDC空间中,近裁剪面是z=-1,远裁剪面是z=1

    投影矩阵做出如下变换
    near => -1
    far => 1

    更多相关内容
  • - 在齐次裁剪空间的基础上进行透视除法(perspective division)或称齐次除法(homogeneous division),得到的坐标叫做NDC空间坐标。 补充渲染流水线: 模型数据-顶点着色 - 曲面细分 - 几何着色器- 裁剪 - NDC空间 ...

    - 在齐次裁剪空间的基础上进行透视除法(perspective division)或称齐次除法(homogeneous division),得到的坐标叫做NDC空间坐标。

    补充渲染流水线:

    模型数据-顶点着色 - 曲面细分 - 几何着色器 - 裁剪 - NDC空间 - 屏幕空间 - 光栅阶段 - 帧缓存

    其中曲面细分和几何着色器是可选项,而从裁剪空间---NDC空间---屏幕空间一般由底层帮我们自动完成。我们的顶点着色器只需要把顶点转换到齐次裁剪空间就可(就是一般所说的输出的positionCS)空间。

    透视除法:就是将齐次裁剪空间坐标positionCS的X,Y,Z分量都除以W分量。

    我们假设在NDC空间中,经过透视除法后的点为:

    ,那么x’,y’,z’的取值范围则在【-1,1】区间内。反推会齐次裁剪空间的公式:

    NDC空间到屏幕空间:顶点着色器我们的输出在齐次裁剪,那么片段着色器的输入是什么呢?不是齐次裁剪空间,也不是NDC空间,而是屏幕空间。

    在Unity中屏幕左下角像素坐标为(0,0),右上角像素坐标为(pixelWidth,pixelHeight),由于当前x,y的坐标范围为【-1,1】,因此是一个缩放的过程,可以用下面公式变换:

    ScreenX = NDCx * pixelWidth/2 + pixelWidth/2;

    ScreenY = NDCy * pixelWidth/2 + pixelWidth/2;

    ScreenZ的值通常为Clipz/Clipw,存入深度缓冲,但也不是必须。

    注意上面所说的屏幕空间和使用unity内置函数o.screenPos = ComputeScreenPos(o.vertex)不同,内置函数直接从齐次裁剪空间转换,没有经过透视除法转换到NDC空间的过程,所以如果使用内置函数,需要自己在片段着色器中不上透视除法。

    如果需要从屏幕空间转换到NDC空间,可以使用内置函数ComputeScreenPos(o.vertex),求得ScreenPos后进行下面公式转换:

    float4 ndcPos = (o.screenPos / o.screenPos.w) * 2 - 1;

    展开全文
  • 《Shader入门精要》中十三章中深度和法线纹理一节,别后的原理中列出了如何从 Z纹理中将本片元的NDC空间下的z值还原成View空间下的z值 附上表达式推导过程,手写 方便和我一样数学都...

    《Shader入门精要》中十三章中深度和法线纹理一节,别后的原理中列出了如何从 Z纹理中将本片元的NDC空间下的z值还原成View空间下的z值




    附上表达式推导过程,手写




    方便和我一样数学都换老师的童鞋,少走弯路,呵呵。



    展开全文
  • 顶点从观察空间变换到裁剪空间

    顶点从观察空间变换到裁剪空间

    1.视截体

    视截体简单的说就是摄像机的可视区域。
    一个正交视图的摄像机,他的视截体是一个长方体。而一个使用了透视视图的摄像机,它的视截体则是一个正棱台。
    在这里插入图片描述

    视截体由多个因素决定。
    1.field of view:视野区域角度,一般是只要知道竖直方向的角度。因为水平方向的视野可以通过aspect参数推出。如上图的∠UOD.
    2.aspect:正棱台的宽高比。W / H。
    3.far:视截体的远截面距离摄像机的距离。
    4.near:视截体的近截面距离摄像机的距离。

    2.投影矩阵

    通过投影矩阵,可以把观察空间里的正棱台视截体形变拉伸为一个长方体的裁剪空间。

    图片来自unity3D内建着色器源码剖析

    裁剪空间在经由透视除法之后,才会转化到宽高取值范围为[-1,1],深度取值为[-1,0]的长方体方体(Direct3D平台)。这种投影变换称为透视投影。转化后的空间叫标准化设备坐标(NDC)。
    下面尝试推导下投影矩阵。
    假设视截体里的一个点P(x,y,z),经过透视投影后转变为NDC坐标的P1(x1, y1, z1)。
    P投影在蓝色投影平面上的一点P1,投影面的高为2

    因为NDC空间的高度正是2,并且在NDC空间中,PP1//AA1。那么上图的OP与蓝色投影线相交的P1点的高度值y1,就是转化到NDC空间后的P1点的y1值。
    现在我们知道摄像机的参数有 纵角度FoY,远近截面f,n,宽高比aspect。
    ∠ U O A 1 = F o Y ∠UOA_{1} = FoY\\ UOA1=FoY
    ∣ U A 1 → ∣ = 1 \left| \overrightarrow{UA_{1}}\right| = 1\\ UA1 =1
    z 1 = − ∣ A 1 O → ∣ = − c t a n ( ∠ U O A 1 2 ) = − c t a n ( F o Y 2 ) z_{1} = -\left| \overrightarrow{A_{1}O}\right| = -ctan(\dfrac{∠UOA_{1}}{2}) = -ctan(\dfrac{FoY}{2}) z1=A1O =ctan(2UOA1)=ctan(2FoY)
    因为△OPA和△OP1A1相似。有
    y 1 z 1 = y z \dfrac{y_{1}}{z_{1}}=\dfrac{y}{z} z1y1=zy
    可以先求得投影后的y1值为
    y 1 = y z . z 1 = − y z . c t a n ( F o Y 2 ) . . . . . . . . . . ① y_{1}=\dfrac{y}{z}. z_{1} =- \dfrac{y}{z}.ctan(\dfrac{FoY}{2})..........① y1=zy.z1=zy.ctan(2FoY)..........
    同理,我们可以把符号y更换为符号x,符号FoY更换为FoX,就可以求得x1的等式。
    x 1 = x z . z 1 = − x z . c t a n ( F o X 2 ) . . . . . . . . . . ② x_{1}=\dfrac{x}{z}. z_{1} =- \dfrac{x}{z}.ctan(\dfrac{FoX}{2})..........② x1=zx.z1=zx.ctan(2FoX)..........

    因为FoX参数未知,我们可以通过已知的aspect和FoY参数,替换掉它。如下图
    在这里插入图片描述
    a s p e c t = W H = c t a n ( F o Y 2 ) . z 1 c t a n ( F o X 2 ) . z 1 aspect=\dfrac{W}{H}=\dfrac{ctan(\dfrac{FoY}{2}).z_{1}}{ctan(\dfrac{FoX}{2}).z_{1}}\\ aspect=HW=ctan(2FoX).z1ctan(2FoY).z1
    c t a n ( F o X 2 ) = c t a n ( F o Y 2 ) a s p e c t . . . . . . . . . . ③ ctan(\dfrac{FoX}{2}) = \dfrac{ctan(\dfrac{FoY}{2})}{aspect}..........③ ctan(2FoX)=aspectctan(2FoY)..........
    ③式代入②式后
    x 1 = x z . z 1 = − x z . c t a n ( F o Y 2 ) a s p e c t x_{1}=\dfrac{x}{z}. z_{1} =- \dfrac{x}{z}.\dfrac{ctan(\dfrac{FoY}{2})}{aspect} x1=zx.z1=zx.aspectctan(2FoY)
    P1的x1,y1的表达式已经有了,P1新的坐标表示为
    P 1 = [ − x z . c t a n ( F o Y 2 ) a s p e c t , − y z . c t a n ( F o Y 2 ) , z 1 ] P_{1}=[- \dfrac{x}{z}.\dfrac{ctan(\dfrac{FoY}{2})}{aspect},- \dfrac{y}{z}.ctan(\dfrac{FoY}{2}),z_{1}] P1=[zx.aspectctan(2FoY),zy.ctan(2FoY),z1]
    齐次化的P1的坐标
    P 1 = [ − x z . c t a n ( F o Y 2 ) a s p e c t , − y z . c t a n ( F o Y 2 ) , z 1 , 1 ] P_{1}=[- \dfrac{x}{z}.\dfrac{ctan(\dfrac{FoY}{2})}{aspect},- \dfrac{y}{z}.ctan(\dfrac{FoY}{2}),z_{1}, 1] P1=[zx.aspectctan(2FoY),zy.ctan(2FoY),z1,1]
    根据齐次坐标的性质,如果第四维w≠0,则(x,y,z,1)等价于(wx,wy,wz,w)。现在把P1 的坐标值乘以−z后
    P 1 = [ x . c t a n ( F o Y 2 ) a s p e c t , y . c t a n ( F o Y 2 ) , − z . z 1 , − z ] . . . . . . . . . . ④ P_{1}=[{x}.\dfrac{ctan(\dfrac{FoY}{2})}{aspect},y.ctan(\dfrac{FoY}{2}),-z.z_{1}, -z]..........④ P1=[x.aspectctan(2FoY),y.ctan(2FoY),z.z1,z]..........
    通过观察P1表达式的特点,P1可以拆分为点(x,y,z,1)右乘一个矩阵Mp
    P 1 = [ c t a n ( F o Y 2 ) a s p e c t 1 1 1 1 c t a n ( F o Y 2 ) 1 1 m 1 m 2 m 3 m 4 0 0 − 1 0 ] . [ x y z 1 ] P_{1}=\begin{bmatrix} \dfrac{ctan(\dfrac{FoY}{2})}{aspect} & 1 & 1 & 1 \\ 1 & ctan(\dfrac{FoY}{2}) & 1 & 1 \\ m1 & m2 & m3 & m4 \\ 0 & 0 & -1 & 0 \end{bmatrix}.\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} P1=aspectctan(2FoY)1m101ctan(2FoY)m2011m3111m40.xyz1
    M p = [ c t a n ( F o Y 2 ) a s p e c t 1 1 1 1 c t a n ( F o Y 2 ) 1 1 m 1 m 2 m 3 m 4 0 0 − 1 0 ] M_{p}=\begin{bmatrix} \dfrac{ctan(\dfrac{FoY}{2})}{aspect} & 1 & 1 & 1 \\ 1 & ctan(\dfrac{FoY}{2}) & 1 & 1 \\ m1 & m2 & m3 & m4 \\ 0 & 0 & -1 & 0 \end{bmatrix} Mp=aspectctan(2FoY)1m101ctan(2FoY)m2011m3111m40
    矩阵Mp中的m1 m2 m3 m4是未知的,且有一下表达式成立
    − z . z 1 = m 1. x + m 2. y + m 3. z + m 4 -z.z_{1}=m1.x + m2.y + m3.z+m4 z.z1=m1.x+m2.y+m3.z+m4
    通过观察式子,可以猜想m1 = 0, m2 = 0(因为式子的左边不存在x和y)。这个也是必然的。因为对于P点,投影到投影面后,z1值都必定一致且和xy的取值无关。
    在这里插入图片描述
    所以上式进一步简化
    − z . z 1 = m 3. z + m 4 -z.z_{1}=m3.z+m4 z.z1=m3.z+m4
    投影后z1的取值范围是[−1,0],显然远截面的z(即−f)投影后的z1 为−1,近截面的z(即−n)投影后z1 为0。把值代入上式解二元一次方程
    { − f ⋅ m 3 + m 4 = f ( − 1 ) m 3 ( − n ) + m 4 = n ( 0 ) . \begin{aligned}\begin{cases}-f\cdot m_{3}+m_{4}=f\left( -1\right) \\ m_{3}\left( -n\right) +m_{4}=n\left( 0\right) \end{cases}\\ .\end{aligned} {fm3+m4=f(1)m3(n)+m4=n(0).
    求得m3 m4的表达式
    m 3 = f f − n m_{3}=\dfrac{f}{f-n} m3=fnf
    m 4 = n f f − n m_{4}=\dfrac{nf}{f-n} m4=fnnf

    最后求得Mp的表达式为
    M p = [ c t a n ( F o Y 2 ) a s p e c t 1 1 1 1 c t a n ( F o Y 2 ) 1 1 0 0 f f − n n f f − n 0 0 − 1 0 ] M_{p}=\begin{bmatrix} \dfrac{ctan(\dfrac{FoY}{2})}{aspect} & 1 & 1 & 1 \\ 1 & ctan(\dfrac{FoY}{2}) & 1 & 1 \\ 0 & 0 & \dfrac{f}{f-n} & \dfrac{nf}{f-n} \\ 0 & 0 & -1 & 0 \end{bmatrix} Mp=aspectctan(2FoY)1001ctan(2FoY)0011fnf111fnnf0
    Mp就是我们的投影矩阵。
    最后有一个需要注意的,我们的观察空间使用的是右手坐标系,而裁剪空间采用左手坐标系,要把Mp右乘一个倒转z轴的矩阵才能得到最终的投影矩阵Mp。
    M p = [ 1 0 0 0 0 1 0 0 0 0 − 1 0 0 0 0 1 ] . [ c t a n ( F o Y 2 ) a s p e c t 1 1 1 1 c t a n ( F o Y 2 ) 1 1 0 0 f f − n n f f − n 0 0 − 1 0 ] M_{p}=\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 &-1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}.\begin{bmatrix} \dfrac{ctan(\dfrac{FoY}{2})}{aspect} & 1 & 1 & 1 \\ 1 & ctan(\dfrac{FoY}{2}) & 1 & 1 \\ 0 & 0 & \dfrac{f}{f-n} & \dfrac{nf}{f-n} \\ 0 & 0 & -1 & 0 \end{bmatrix} Mp=1000010000100001.aspectctan(2FoY)1001ctan(2FoY)0011fnf111fnnf0
    M p = [ c t a n ( F o Y 2 ) a s p e c t 1 1 1 1 c t a n ( F o Y 2 ) 1 1 0 0 f n − f n f n − f 0 0 − 1 0 ] M_{p}=\begin{bmatrix} \dfrac{ctan(\dfrac{FoY}{2})}{aspect} & 1 & 1 & 1 \\ 1 & ctan(\dfrac{FoY}{2}) & 1 & 1 \\ 0 & 0 & \dfrac{f}{n-f} & \dfrac{nf}{n-f} \\ 0 & 0 & -1 & 0 \end{bmatrix} Mp=aspectctan(2FoY)1001ctan(2FoY)0011nff111nfnf0
    因为在④的时候为了转化齐次坐标,乘了-z值。所以投影矩阵Mp乘以P点得到到的裁剪空间的P1坐标的w值并非为1,也即使说,P1点没有做透视除法。最后要把的到的P1点的所有坐标值除以它的w值(也是P点的z值),后才是NDC中的坐标值。
    P N D C = M p . P w P_{NDC}= \dfrac{M_{p}.P}{w} PNDC=wMp.P

    推导完结了。

    3.举个栗子

    现在有一个物体Cube,它呆在一个使用透视的摄像机前。我们可以在Unity通过坐标转化的方式,模拟它投影到屏幕前的样子。

    所用到的场景中的物体有
    一个透视投影的摄像机 MainCamera
    一个任你摆布的模型cube Cube
    一个表示NDC空间原点的空物体 ndcspace,这个空物体摆在世界坐标的原点。

    步骤:
    1.取得模型上的所有顶点
    2.顶点坐标需要转化->世界坐标->观察空间坐标P。
    3.P点右乘Mp投影矩阵,就可以的得到一个裁剪空间上的坐标P1。
    3.P1还需要做透视除法处理:除以P1的w分量。
    4.把所有的生成的P1点通过mesh连接起来,生成一个新的cube,放置在ndcspace节点的位置。
    5.把Game视图的窗口设置为1:1,因为要和我们生成的NDC空间大小要一致,方便查看效果。
    6.在scene视图,选择正交模式,沿着z轴的正方向观察ndcspace节点。

    移动cube,观察生成的mesh和屏幕上的cube的投影。

    对比生成的mesh和投影后的cube
    在scene视图正交模式观察的mesh的表现,和投影在屏幕的cube的表现完全一致。

    把cube拖到右上角,和屏幕的右上对其,mesh也和NDC的边缘对齐。
    在这里插入图片描述
    工程地址

    矩阵的推导部分思路来自 《unity3d内建着色器源码剖析》一书,有解读的不对的地方望大佬们指出。

    展开全文
  • NDC坐标是世界空间坐标通过MVP变换之后再进行归一化得到的坐标。只需要再一步变换就能得到屏幕空间坐标。顺便提一下因为已经归一化了,如果需要从NDC坐标还原成世界坐标,需要注意最后除w分量。 何为线性何为非线性 ...
  • opengl 中的透视除法和NDC

    千次阅读 2019-11-26 14:15:35
    OpenGL的坐标空间是[-1, 1],x,y轴超过该区域的都将被切掉 看不见。 viewport像素是 1280 X 720,归一化后坐标空间从[1280X720],映射到[-1,1] 问题:导致物体变形,因为 x,y轴坐标长度都是1 - (-1)= 2,但x,y轴...
  • shader数学基础--坐标空间
  • NDC(归一化的设备坐标)坐标转换到世界坐标要点 参考资料 How to go from device coordinates back to worldspace http://feepingcreature.github.io/math.html 《Unity Shader入门精要》 前情提要,从运动模糊...
  • WebGL空间变换 局部坐标系——》世界坐标系——》相机坐标系——》剪裁坐标系——》规范化设备坐标系——》屏幕坐标系 模型变换:world.xyzw = modelMatrix * position.xyzw; 视图变换::eye.xyzw = viewMaterix * ...
  • 5.6.3.3 设备坐标标准化 (NDC)

    千次阅读 2015-11-22 09:43:46
    上一节中的投影点的坐标在视觉空间中计算。在视觉空间中,投影窗口具有为2的高度和2r的宽度,其中r是纵横比。这样做的问题是,该尺寸取决于纵横比。这意味着我们需要告诉硬件的高宽比,因为硬件将在以后需要做一些...
  • 2、Fragment Shader 在 fs 中,执行透视除法,将 v_screenPos 转换到 NDC空间, NDC 空间中的 z 值,就是深度值。 麒麟子在这里写了两种深度显示方法,depth_8bits 用于 R 通道存储, depth_32bits 用于RGBA 四通道...
  • 空间变换2-灯光空间(ViewMatrix,ProjectionMatrix) @Author:白袍小道 目录XDRender_HLSL_LightMAtrix. 空间变换2-灯光空间(ViewMatrix,ProjectionMatrix)前言正文理论一、行主序和列主序二、ViewMatrix推导过程三...
  • 根据深度重建世界坐标证明世界坐标重建正确的方法首先,得先找到一种证明反推回世界空间位置正确的方法。这里,我在相机前摆放几个物体,尽量使之在世界坐标下的位置小于1,方便判定颜色如下图:然后将几个物体的...
  • 较真一下OpenGL Clip Space和NDC

    万次阅读 2013-08-03 20:15:14
    看到这儿我困惑了一下,查了查以前写的博客,我是这样认为的:经过投影矩阵,顶点被变换到投影空间,即clip space,然后再经过透视除法,顶点被变换到NDC。 这个地方其实应该只是一处笔误(或者说作者意思nds是...
  • 透视投影会将坐标由观察空间投影到NDC空间中,而其中的x,y坐标比较简单,通过相似三角形的原理,将坐标投影到近平面,得到的二维坐标再经过一点线性变换就是NDC坐标的前两个分量. 如下图,p’在近平面np上可以得到一...
  • Transform 和 Coordinate Spaces》 中 有说过 PBRT 中的各种空间,这次主要记录某一些空间之间的变换是怎么进行的,主要是考虑透视投影。 1. CameraToScreen ( Camera space To Screen space, 注意这里的 Screen...
  • 看了下网上关于用UE4描边的案例,发现几乎都是基于屏幕空间后处理通过Slobe算法做描边的案例(也可以理解,毕竟在UE中写Shader这件事相对Unity还是有点复杂),这种描边方案不太好控制,所以一开始就毙掉了。...
  • Unity URP中根据深度重建世界坐标

    千次阅读 2021-10-24 15:47:56
    在相机前摆放几个物体,尽量使之在世界坐标下的位置小于1,方便判定颜色,然后将几个物体的shader换成如下的一个打印世界空间位置的shader: //打印在世界空间位置 Shader "Universal Render Pipeline/Dejavu/...
  • //屏幕坐标系变换到NDC标准设备空间 vec4 ndcPosition = viewPortMatrixInverse * vec4 ( gl_FragCoord . xyz , 1.0 ) ; //标准设备空间变换到剪裁空间 vec4 clipPosition = ndcPosition / gl_...
  • 阴影贴图2

    2017-11-28 21:53:11
    我们知道在NDC空间中,顶点的X,Y分量都位于[-1,1]范围内,在上面的第四步中光栅化程序将NDC空间中的坐标映射到屏幕空间中,并且用它们来存放深度信息。现在我们想要从中提取出深度信息,为此我们需要一个位于[0,1...
  • webgl的ndc大家已经很熟悉了是一个位于中心点(0,0,0)xyz为2✖️2✖️2的空间,webgl程序中矩阵变换的目的,就是把想看的物体都变换到这个坐标系下。webgpu的ndc是中心点位于(0,0,0.5)的xyz为2✖️2✖️1的空间。...
  • 数学基础——MVP矩阵

    千次阅读 2021-12-15 16:53:51
    顶点坐标起始于局部空间(Local Space),之后变为世界坐标(World Coordinate),观察坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后以屏幕坐标(Screen Coordinate)的形式结束 1.M矩阵 模型空间...
  • UE4后期处理材质:扁平化风格描边

    千次阅读 2020-12-03 13:00:01
    下图为"色调映射后":在后期处理的最后阶段从低动态范围空间提取GBuffer 下图为"色调映射前":在高动态范围空间内提取GBuffer 2、创建多边形描边 创建扁平化着色、描边、绘画风格等效果,并将其应用于整个关卡或...
  • d3d 投影矩阵

    2018-03-09 10:08:30
    从上一篇技术博客 软件光栅器三之世界矩阵,相机变换矩阵,透视投影矩阵,透视除法,视口变换矩阵 我们直接给出了各大变换矩阵的表示形式以及实现的代码这一节博客 我将讲述从一个顶点从相机空间到到视平面的坐标...
  • https://www.learnopengles.com/tag/perspective-divide/
  • 喂顶点数据给OpenGL去渲染的时候,OpenGL 需要的顶点数据是要在NDC空间中的,也就是,如果你的vertex shader 什么转换都不做,提供给VBO的顶点坐标,需要时NDC空间的,如果你提供给VBO的顶点数据并不是NDC空间的话,...
  • 模型坐标转换到NDC 1.模型坐标到世界坐标 2.世界坐标到观察坐标 3.观察坐标到裁剪坐标 4.裁剪坐标透视除法转换为NDC(归一化设备坐标) 透视投影 其中: nearClipPlaneHeight = 2 * Near(摄像机到近裁剪...
  • 三维数学基础4:坐标空间空间转换 通过4x4矩阵可以把变换作用于点或方向矢量上。进一步延伸到刚体,只需把物体当做无数个点,把变换施加在这些点上,即能实现将变换运用在物体上。 在计算机图形学里,物体通常由...
  • 3D游戏中的坐标变换一直都是基础中的基础,了解了坐标变换,你就了解了一个3d模型是如何转换到2D屏幕中的。 模型空间->世界空间->...我们需要使用齐次空间,就是将空间升维到4维空间,因此世界空间

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,959
精华内容 1,183
关键字:

ndc空间