美文网首页
Clip Space、NDC、Screen Space

Clip Space、NDC、Screen Space

作者: 雄关漫道从头越 | 来源:发表于2020-08-03 21:30 被阅读0次

    Unity3D - Shader - 模型、世界、观察、裁剪空间坐标转换
    Unity3D Shaders中Loacl、World、Camera space之间的转换(翻译)
    容易混淆的Clip Space vs NDC,透视除法

    先看两张图片:


    空间转换流程图 空间变换

    可以看到裁剪空间(Clip Space)最后会转换到屏幕空间(Screen Space),最终输出到屏幕上并显示正确的图像,模型空间-->世界空间-->观察空间,这几步是比较容易理解的,直接通过矩阵转换就可以得到相应的坐标,但是裁剪空间-->屏幕空间,其实还有两个中间步骤:转换到NDC(标准化设备坐标)与屏幕映射(OpenGL好像叫视口变换)。
    先解释下裁剪空间,观察空间实际就是相机为原点的空间,而相机可分为透视模式和正交模式,透视模式的可视区域是一个梯形的椎体,正交模式是一个矩形,如下:

    透视投影
    正交投影

    无论哪种模式,都是有可视范围的,超出可视范围(近裁剪平面、远裁剪平面和上下左右边界)的物体就看不到,看不到的东西就没有必要渲染,所以要将不可见的物体裁剪掉,留下可见的范围内的物体就可以了,所以裁剪空间实际上是在观察空间的基础上增加了一个区域限制,把坐标限制在可见的范围内。

    转换到裁剪空间后经过GPU的裁剪处理就可以得到最终需要被渲染的物体顶点坐标了,接下来GPU会做透视除法将顶点转换到NDC中,透视除法将裁剪空间中顶点的4个分量都除以w分量,就从裁剪空间转换到了NDC了,NDC是一个长宽高取值范围为[-1,1]的立方体,具体的推导就不展开说了,网上有很多大牛的详细推导过程。


    NDC

    注:在DirectX里面,NDC的z方向取值范围是[0,1],在Unity中可以用UNITY_NEAR_CLIP_VALUE获取z方向近平面的值,在openGL环境下是-1.0,DirectX中是0.0。

    将顶点坐标都转换到NDC后,下一步就是屏幕映射,这个就取决于最终要渲染到的窗体分辨率,注意是窗体分辨率,不是屏幕分辨率,因为在移动平台上一般不允许改变渲染窗体的分辨率,通常是全屏显示,也就是屏幕分辨率,而pc上修改窗体大小改变分辨率就比较普遍,最终通过屏幕映射得到屏幕空间的坐标。在Unity中,屏幕空间左下角的像素坐标是(0,0),右上角是(pixelWidth,pixelHeight)。
    (Vertex Shader) => Clip Space => (透视除法) => NDC => (视口变换) => Screen Space => (Fragment Shader)
    不过这些Unity会自动帮助我们完成,我们只需要知道原理就可以了。

    相关文章

      网友评论

          本文标题:Clip Space、NDC、Screen Space

          本文链接:https://www.haomeiwen.com/subject/lsmbrktx.html