[Unity]基于深度缓冲实现扫描效果

在这里插入图片描述
在这里插入图片描述
如果想看视频的话,可以观看我在B站翻译的教程:BV1vt4y1U7HV
实现扫描效果不可能对每个着色器都去增加一段shader代码来实现扫描效果,这是不合理的,不利于项目扩展。所以正确的做法是对于屏幕中看到的像素去做处理,也就是像后处理一样,把rendertexture进行处理后在渲染在屏幕上。

获取深度缓冲

在获取当前渲染的摄像机组件后,对其成员depthTextureMode 赋值就能获得深度贴图。

GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;

于是shader中就能够通过声明sampler2D _CameraDepthTexture来获取深度贴图。
亲自尝试了发现:
如果场景中有灯光能投射阴影,即使不去设置摄像机的深度贴图模式也能获取到深度贴图。

重构空间坐标

因为要实现扫描效果,我们需要计算像素点离扫描点的距离。但如何获得空间顶点坐标呢?因为是后处理,所以在shader中处理的顶点其实只有屏幕四个角落的点。所以想要获取当前像素在世界空间的坐标,我们需要使用深度贴图来重构世界空间坐标。
重构空间坐标有两种方法

  • 构建出当前像素的NDC坐标,再通过当前摄像机的视角*投影矩阵的逆矩阵来得到世界空间下的像素坐标。(但这需要在片元着色器中进行矩阵乘法操作,会影响游戏性能)
  • 对图像空间下的视锥体射线(从摄像机触发,指向图像上的某点的射线)进行插值,这条射线存储了该像素在世界空间下到摄像机的方向信息。然后,我们把该射线和线性化后的视角空间下的深度值相乘,再加上摄像机的世界位置,就可以得到该像素在世界空间下的位置。
  • 在这里插入图片描述

计算视锥体射线

		float camFar = Camera.main.farClipPlane;
        float camFov = Camera.main.fieldOfView;
        float camAspect = Camera.main.aspect;

        float fovWHalf = camFov * 0.5f;

        Vector3 toRight = Camera.main.transform.right * Mathf.Tan(fovWHalf * Mathf.Deg2Rad) * camAspect;
        Vector3 toTop = Camera.main.transform.up * Mathf.Tan(fovWHalf * Mathf.Deg2Rad);

        Vector3 topLeft = (Camera.main.transform.forward - toRight + toTop);
        float camScale = topLeft.magnitude * camFar;

        topLeft.Normalize();
        topLeft *= camScale;

        Vector3 topRight = (Camera.main.transform.forward + toRigh
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值