如何从深度纹理重构世界坐标

游戏特效,后处理是必不可少的,而后处理经常需要我们得到当前画面的像素对应世界空间的所有信息。

思路

  1. 通过深度纹理取得NDC坐标,然后再通过NDC坐标还原成世界空间坐标
//csharp脚本部分
Matrix4x4 matrix = camera.projectionMatrix * camera * worldToCameraMatrix;
Matrix4x4 InverseMatrix = matrix.inverse; //shader部分
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth);
float4 H = float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, d * 2 - 1, 1);
float D = mul(InverseMatrix, H);
float worldPos = D/D.w

计算量比较大,一般用下面的方法。

2. 通过得到相机的坐标以及在世界空间下像素和相机的偏移量,通过两者相加得到像素的世界坐标。这里偏移量通过顶点的线性深度乘以顶点着色器输出并被插值后所得的相机指向像素的射线来得到。

float4 worldPos = _WorldSpaceCameraPos + linearDepth * interpolatedRay;

接下来来介绍这种办法计算的过程。

我们很容易计算出相机到近平面四个顶点的向量方向以及世界空间下的长度,只需要得到相机记录的fov,aspect等信息





我们要得到的是像素的世界坐标。

这里有个很重要的点,相机能看到这个像素,必然说明原本的世界坐标的点和在近平面的投影点(像素位置)处于相机相机指向像素的射线的方向上。也就是下面13.7图。



所以问题转为如何得出相机到像素所对应的世界坐标的向量的长度

很幸运的是我们拥有深度纹理,所以13.7图的depth是已知的。

那么如何通过depth来得到dist,这里书本上举例的是TL点的计算。



单单看这个点的计算是没问题的,自己手画一个就能得出结果。但关键是为什么所有点都满足,这里设世界坐标下任意一点A。



其和相机的连线经过近平面并产生交点



画出near向量



延长near到长度和A点的z变量,也就是depth一样长,并且做三角形OAB和ODC

这张有点乱,希望大家不要嫌弃,真的不太懂怎么安排线



很容易发现三角形ODC ~ 三角形OAB

得到长度关系

|near| / |interpolatedRay| = |depth| / |dist|

对任意点都是适用的


所以

|dist| = |depth| * (|interpolatedRay| / |near|)

这里的depth是线性深度,也就是坐标的z分量。

对应书上片元着色器的部分就是这部分代码。



而书本计算interpolatedRay借助了Shader的插值。

那么现在关键就在于平面的四个顶点的(interpolatedRay / |near|)在顶点着色器输出后插值得到的到底是不是每个像素对应的 (interpolatedRay / |near|) 。其次|near|是一个常数,所以只需要论证interpolatedRay是否正确即可。

求助

可惜的是我网上找了很久还是不知道向量是如何插值的,希望有大佬知道的可以告诉我。

2D情况下

可能只想要得到近平面的像素点(平面本身构成的图片的像素)在世界空间下的位置,只需要计算出相机到近平面的四个顶点的向量直接插值,无需任何深度纹理的信息。

也就是书上的这部分代码无需乘scale



并且计算公式变为

float4 worldPos = _WorldSpaceCameraPos + interpolatedRay;

这样子的情况下,雾效的产生将和相机直接挂钩,相机的近平面就是雾效产生的地方,可以在2D游戏中使用。

Re:《Unity Shader入门精要》13.3全局雾效--如何从深度纹理重构世界坐标的更多相关文章

  1. Unity Shader入门精要读书笔记(一)序章

    本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数 ...

  2. 【我的书】《Unity Shader入门精要》出版上市

    重要的事 先说重要的事,就是我的书籍<Unity Shader入门精要>在经过无数次跳票后,终于出版上市了(泪目-)! 购买传送门: 亚马逊 当当 京东 截止到我写这篇文章的时候,京东是没 ...

  3. Unity Shader入门精要之 screen post-processing effect

    本篇记录了学习Unity Shader入门精要的屏幕后处理的一些知识点. OnRenderImage(RenderTexture src, RenderTexture dest) 以上函数是Unity ...

  4. Unity Shader入门精要学习笔记 - 第17章 Unity的表面着色器探秘

    转自 冯乐乐的<Unity Shader 入门精要> 2010年的Unity 3 中,Surface Shader 出现了. 表面着色器的一个例子. 我们先做如下准备工作. 1)新建一个场 ...

  5. Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术

    转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...

  6. Unity Shader入门精要学习笔记 - 第15章 使用噪声

    转载自 冯乐乐的 <Unity Shader 入门精要> 消融效果 消融效果常见于游戏中的角色死亡.地图烧毁等效果.这这些效果中,消融往往从不同的区域开始,并向看似随机的方向扩张,最后整个 ...

  7. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  8. Unity Shader入门精要学习笔记 - 第11章 让画面动起来

    转自 冯乐乐的 <Unity Shader入门精要> Unity Shader 中的内置变量 动画效果往往都是把时间添加到一些变量的计算中,以便在时间变化时画面也可以随之变化.Unity ...

  9. Unity Shader入门精要学习笔记 - 第10章 高级纹理

    转载自 冯乐乐的 <Unity Shader入门精要> 立方体纹理 在图形学中,立方体纹理是环境映射的一种实现方法.环境映射可以模拟物体周围的环境,而使用了环境映射的物体可以看起来像镀了层 ...

随机推荐

  1. 解决Android3.0之后不能在主线程中进行HTTP请求

    感谢大佬:https://www.cnblogs.com/falzy/p/5763848.html 在Android3.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求,运行时 ...

  2. JScrollPane 自动跟进 自动到滚动到最底部

    感谢大佬:https://blog.csdn.net/csdn_lqr/article/details/51068423 注:以下方法为网上摘抄 1 . JTable( 放在JScrollPane中  ...

  3. 问题描述:Navicat连不上MySQL数据库

    发现Navicat连不上MySQL后我首先觉得是MySQL的服务没有打开, 然后再cmd里面 启动MySQL服务 输入: net start mysql 发现没有此服务,然我网上找了一下 先初始化My ...

  4. pyrealsense2学习

    如何得到realsense设备信息 前提:将D455连接在电脑上,并且已经下载好 Realsense Viewer 打开Realsense Viewer--> Info, 便可得到相机的一些参数 ...

  5. 浅谈Java中重写与重载的区别

    重载和重写是Java中两个截然不同的概念.但是却因为名字相近导致很多人经常混淆. 下面用例子展示出他们之间的区别. 在Java中,重载(overloading) 发生在本类.方法名相同,参数列表不同, ...

  6. 总结Tomcat优化方法

    一.内存空间优化 配置文件目录:/usr/local/tomcat/bin/catalina.sh JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= ...

  7. 通过安装HomeBrew来安装Python3

    首先说什么是HomeBrew? 下面引用简书上一个博客的解释:(博客链接:http://www.jianshu.com/p/d229ac7fe77d) 为什么要使用Homebrew Mac OS X是 ...

  8. Solution -「CF 1375G」Tree Modification

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个结点的树,每次操作选择三个结点 \(a,b,c\),满足 \((a,b),(b,c)\in E\),并令 ...

  9. MyBatis功能点二应用:第三方分页插件使用

    pageHelper分⻚插件使用 在前面文章MyBatis功能点二:plugins插件使用 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了自定义插件的使用,本文介绍第三方插件pa ...

  10. (待补充)diff 算法解析

    今天,学习React的时候,底层提到了 diff算法,顺藤摸瓜, 也发现了VUE也使用了diff算法. mark一下,后续补充 infoq-VUE-diff算法 react-diff算法