本篇讲一下相交检测的优化。有两个措施。

线段相交检测

之前的检测都是检测光线的终点是否在物体内。我们可以尝试检测光线的线段是否与物体相交。

比如说有一个非常薄的物体,光线差不多垂直于它的表面。如果用普通的方法的话,这个平面可能就会被光线跳过了。

我们将一个像素的厚度看做一维数轴上的一条线段,起点是其深度。同时将光线的起点、终点的深度值也用同样的方法看做一条线段。此时我们去检测这两条线段是否有重合。有的话则证明相交。

用这种方法可以解决薄的物体被跳过的问题。

			bool intersect(float raya, float rayb, float2 sspt) {        //raya rayb是光线两端的深度值,sspt是屏幕空间的坐标点。
float screenPCameraDepth = Linear01Depth(tex2Dlod(_CameraDepthTexture, float4(sspt / 2 + 0.5, 0, 0)));
float backZ = tex2Dlod(_BackfaceTex, float4(sspt / 2 + 0.5, 0, 0)).r; if (raya > rayb) { //因为光线方向不定(可能朝向+z或者-z)需要排序
float t = raya;
raya = rayb;
rayb = t;
}
return raya < backZ && rayb > screenPCameraDepth;
}

为了优化效果,我们在计算光线的屏幕空间的坐标时,可以取光线两个端点的中间点,投影到屏幕上作为采样点。

二分搜索优化

大部分情况下,我们的每个像素的采样次数不会很高。此时采样的质量会比较差。我们可以引入二分搜索,当检测到一个光线的相交时,我们在这段光线内部进行二分搜索,寻找精确的相交点。

这个图不好截,我找了kode80博客里的一张图进行说明。

值得注意的是,二分搜索只能对成功相交的光线进行优化,本身没有相交的是无法进行优化的。

以下代码中涉及到一些下篇的变量,但是大体意思很明了,即退回一段光线,然后在退回的区间中寻找相交。

if (intersect(screenPTrueDepth,prevDepth, screenPCurrent - dScreenPCurrent/2)){
#if 1 //二分搜索优化
float gapSize = PIXEL_STRIDE;
float2 screenPBegin = screenPCurrent - dScreenPCurrent; //回退
float oneOverZBegin = oneOverzCurrent - dOneOverZCurrent;
prevDepth = 1 / oneOverZBegin / -_ProjectionParams.z;
UNITY_LOOP
for (int j = 0; j < 10 && gapSize > 1.0; j++) {
gapSize /= 2;
dScreenPCurrent /= 2;
dOneOverZCurrent /= 2;
screenPCurrent = screenPBegin + dScreenPCurrent;
oneOverzCurrent = oneOverZBegin + dOneOverZCurrent;
screenPTrueDepth = 1 / oneOverzCurrent / -_ProjectionParams.z;
if (intersect(screenPTrueDepth, prevDepth, screenPCurrent)) { //命中了,起点不用动。(长度缩短一半即可) }
else { //没命中,将起点移动到中间。
prevDepth = screenPTrueDepth;
screenPBegin = screenPCurrent;
oneOverZBegin = oneOverzCurrent;
}
}
#endif
hitPixel = screenPCurrent / 2 + 0.5;
rayPercent = (float)i / STEP_COUNT;
return true;

在Unity中实现屏幕空间反射Screen Space Reflection(3)的更多相关文章

  1. 在Unity中实现屏幕空间反射Screen Space Reflection(4)

    第四部分讲一下如何在2D屏幕空间步进光线. http://casual-effects.blogspot.com/2014/08/screen-space-ray-tracing.html 中的代码感 ...

  2. 在Unity中实现屏幕空间反射Screen Space Reflection(1)

    本篇文章我会介绍一下我自己在Unity中实现的SSR效果 出发点是理解SSR效果的原理,因此最终效果不是非常完美的(代码都是够用就行),但是从学习的角度来说足以学习到SSR中的核心算法. 如果对核心算 ...

  3. 在Unity中实现屏幕空间反射Screen Space Reflection(2)

    traceRay函数 在上一篇中,我们有如下签名的traceRay函数 bool traceRay(float3 start, float3 direction, out float2 hitPixe ...

  4. 高级屏幕空间反射: Screen Space Reflection (SSSR)

    SSSR进一步调优,对标寒霜级技术水平,实现方式为Direct3D 11+自主实现实时渲染引擎,方法为对比测试.实现已经有段时间了,还是简要更新下吧.以下画面中的SSSR效果全部采用1:4 resol ...

  5. 高级屏幕空间反射: Screen Space Reflection (SSR)

    自从CE3首倡SSR以来,发展至今,其质量与当年早已不能同日而语.不仅强调超越性的质量,而且强调超越性的性能.乘着周末有空撸了撸,以下是增强型实时SSR结果图.与我原来的SSR原始实现相比,新的增强型 ...

  6. screen space reflection/soft alpha test/

    http://www.crytek.com/cryengine/presentations/secrets-of-cryengine-3-graphics-technology 很多宝贝里面 不止题目 ...

  7. 在Unity中实现屏幕空间阴影(1)

    接着上篇文章,我们实现了SSR效果. 其中的在屏幕空间进行光线追踪的方法是通用的.借此我们再实现一种屏幕空间的效果,即屏幕空间阴影. 文中的图片来自Catlike coding http://catl ...

  8. 在Unity中实现屏幕空间阴影(2)

    参考文章: https://www.imgtec.com/blog/implementing-fast-ray-traced-soft-shadows-in-a-game-engine/ 完成的工程: ...

  9. 关于Unity中的屏幕适配

    一.Game视图的屏幕分辨率可以先自定义添加,供以后选择,以下是手游经常用到的分辨率: 1.1136X640,iPhone5 2.1920X1080,横屏,主流游戏都是这个分辨率 3.1080X192 ...

随机推荐

  1. 运维工程师如果将web服务http专变为https

    1:生成私钥   2:生成证书签署请求   3:在提供CA签署的web网站上,提交生成的证书签署请求   4:下载已经签署的CA证书   5:将证书的信息保留在web服务器中,且应用到提供web服务的 ...

  2. 复利计算器Junit单元测试

    一.测试场景 测试模块 测试输入 预期结果 运行结果 bug跟踪 复利计算 (本金,利率,年限,次数) 终值     测试运算结果 (100,5,3,1) 115.76 115.76   测试输入负数 ...

  3. excel表中判断A列与B列内容是否相同,相同的话在C列按条件输出!

    判断两列数据是否相同,有以下几个函数判断(做笔记于此,方便以后查找): 1.=IF(AND(A4=B4),"相同","") 在C列输出相同字符 2.=IF(A1 ...

  4. vue h render function & render select with options bug

    vue h render function & render select with options bug https://github.com/xgqfrms/vue/issues/41 ...

  5. UVA11737_Extreme Primitive Society

    这是隐藏的最深的一个水题.其隐藏性能如此之好,是因为题目的描述十分蛋疼,写了好多好多的废话. 让我们这种过不了六级的孩子情何以堪啊. 是这样的,给你若干个矩形,每次在所有的矩形中两两组合形成许多许多新 ...

  6. 【bzoj1297】[SCOI2009]迷路 矩阵乘法

    题目描述 给出一个 $n$ 个点的有向图,每条边的权值都在 $[1,9]$ 之间.给出 $t$ ,求从 $1$ 到 $n$ ,经过路径边权和恰好为 $t$ 的方案数模2009. 输入 第一行包含两个整 ...

  7. BZOJ3743 COCI2015Kamp(树形dp)

    设f[i]为由i开始遍历完子树内所要求的点的最短时间,g[i]为由i开始遍历完子树内所要求的点最后回到i的最短时间.则g[i]=Σ(g[j]+2),f[i]=min{g[i]-g[j]+f[j]-1} ...

  8. # HNOI2012 ~ HNOI2018 题解

    HNOI2012 题解 [HNOI2012]永无乡 Tag:线段树合并.启发式合并 联通块合并问题. 属于\(easy\)题,直接线段树合并 或 启发式合并即可. [HNOI2012]排队 Tag:组 ...

  9. arp 投毒实验

    1.查看kali2.0和kali2.0.0的IP地址,如图1和图2,其中192.168.1.133作为攻击者,192.168.1.109作为PC访问FTP服务器192.168.1.234 图1 图2 ...

  10. Codeforces 582C. Superior Periodic Subarrays(数学+计数)

    首先可以把 i mod n=j mod n的看成是同一类,i mod s=j mod s的也看成是同一类,也就是i mod gcd(s,n)的是同一类,很好理解,但是不会数学证明...大概可以想成数轴 ...