从depth buffer中构建view-space position

观察透视投影矩阵:

对于x和y,矩阵变换只是一个缩放系数,那么逆变换就是缩放系数的倒数,所以

设Xndc Yndc为NDC空间中的XY坐标,Xview Yview Zview为view space中的坐标,则

所以

所以已知XY的NDC坐标和view space z,就能求出view space position,写成代码就是:

float M = tan(fov*0.5f)*aspect;
float N = tan(fov*0.5f);
float3 GetViewSpacePos(float2 NDCPos, float ViewSpaceZ)
{
    float3 VPos = float3(NDCPos.xy, 1.f) * float3(M, N, 1.f);
    return VPos * ViewSpaceZ;
}

如果depth buffer中已经存储了线性的view space depth,那么只需采样出depth,然后计算出position即可;如果depth buffer中储存的是非线性的perspective z(NDC z),那么需要先把perspective z逆变换为view space z,再使用上述方法计算position。

把perspective z变换为view space z:

对于view space z,乘以投影矩阵然后除以w得到ndc z:

由上式可得:

其中

写成代码就是:

float P0 = 1/zn;
float Q = zf/(zf - zn);
float P1 = 1/(zn*Q);

float PerpectiveZToLinearZ(float Zndc)
{
    return 1.f / (P0 - P1 * Zndc);
}

所以对于perspective z,构建view-space postion的代码如下:

float3 GetViewSpacePos_NDCZ(float2 NDCPos, float Zndc)
{
    float ViewSpaceZ = PerspectiveZToLinearZ(Zndc);    return GetViewSpacePos(NDCPos, ViewSpaceZ);}
时间: 2024-10-24 14:39:58

从depth buffer中构建view-space position的相关文章

测试不同格式下depth buffer的精度

这篇文章主要是参考MJP的"Attack of The Depth Buffer",测试不同格式下depth buffer的精度. 测试的depth buffer包含两类: 一是非线性的depth buffer,存储着perspective z(也就是最常用的,透视投影后归一化的z/w的buffer),二是线性的depth buffer,存储着view space z(这里的线性指的是在view space 中是否线性).测试的格式包括16位浮点数,32位浮点数,16位定点数,还有最常

D3D depth buffer的预览

在使用D3D开发游戏的过程中,很多情况下都会用到depth buffer来完成特定的效果,比如DOF,Shadows,SSAO等等.在这些情况下我们就可能需要预览depth buffer来确定它是正确的,以免导致后续运算渲染出错.此时有一个问题就出现了,因为原始的depth buffer中保存的depth不是线性的.我们知道,世界坐标系下的顶点在经过视图变换后会被转换到视图空间,此时摄像机在原点,并且我们为摄像机定义了一个近平面和一个远平面: 在经过视图变换后,接着执行的就是投影变换,D3D的透

[Zz] DX depth buffer

声明:本文完全翻译自DX SDK Documentation depth buffer,通常被称为z-buffer或者w-buffer,是设备的一个属性,用来存储深度信息,被D3D使用.当D3D渲染一个场景到target surface的时候,它会使用depth-buffer surface上的数据,来决定被rasterized三角面片的pixel间的遮挡关系. 当depth buffer被开启,rendering surface上的每一个点都会被检测.depth buffer上的值可以是点的z

使用Koloda View在Swift中构建类似Tinder(国内的探探社交应用)的卡片

在过去几年中,随着社交网络应用程序的普及,约会应用程序也迅速出现.其中一个最突出的应用是Tinder.它不仅是一个很棒的约会应用程序,而且还在视图动画或过渡方面创建了新的iOS趋势,例如Tinder Card Swipe或Tinder UI 在这个iOS教程中,我们将学习如何在Swift中构建Tinder Swipe Cards,以便您可以将此功能包含在iOS应用程序中.目前有一些图库支持这种类型的可滑动卡片,其中一个是KolodaView.在本教程中,我们将向您展示如何使用代码示例在Swift

如何在Android的ListView中构建CheckBox和RadioButton列表(Android版支持单选和多选的投票项目)

引言 我们在android的APP开发中有时候会碰到提供一个选项列表供用户选择的需求,如在投票类型的项目中,我们提供一些主题给用户选择,每个主题有若干选项,用户对这些主题的选项进行选择,然后提交. 本文以一个支持单选和多选投票项目为例,演示了在一个ListView中如何构建CheckBox列表和RadioButton列表,并分析了实现的原理和思路,提供有需要的朋友参考. 项目的演示效果如下. 数据源 通常我们的数据源来自于数据库.首先,我们构建投票项目类SubjectItem. /** * 主题

android中自定义view涉及到的绘制知识

android中自定义view的过程中,需要了解的绘制知识. 1.画笔paint: 画笔设置: <span style="font-size:14px;"> paint.setAntiAlias(true);//抗锯齿功能 paint.setColor(Color.RED); //设置画笔颜色 paint.setStyle(Style.FILL);//设置填充样式 paint.setStrokeWidth(30);//设置画笔宽度 paint.setShadowLayer(

ListVIew中插入view

public class MainActivity extends Activity { private ListView listview; private List<String> dataList = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(

ListView onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id)参数详解

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {         parent.getAdapter().getItem(position);         (CircleImageView) view.findViewById(R.id.img_jobberinfo_head);     } 后面有4个参数,乍看直接晕菜,那么每个参数究竟是何意义呢. 举个例子会理解的更快:X

(转)MFC中Doc,View,MainFrmae,App各指针的互相获取

App是应用域,所有的域中的东西都可以通过全局函数访问到它. MainFrame是主框架,也基本可以用全局函数访问到. MainFrame下是若干个ChildFrame,ChildFrame中若干个View和Document(可能不成对),ChildFrame管理着View,View和Document进行互操作. 因此整体框架就出来了,一般除了直接应用的关系都可以通过MainFrame-->Active ChildFrame-->Active View-->Document这条线进行访问