跳至主要內容

VR 后处理效果

muzzik大约 2 分钟文章图形学虚拟现实VRCocosCreator

# 前言

相信当年 VR 刚出的时候大家都体验过吧?这里就用 cocos 的后处理来实现 VR 效果
从其他的 VR 应用可以看出来,手机 VR 画面是由 左右两个相同的类似老电视机画面组成
那么就从这里入手,去逛了下 shadertoyopen in new window,果然找到一个类似的 效果open in new window,然后搬到了 creator 里面,接下来我们看看是 VR 效果具体如何实现的

# 实现

1. 把屏幕分成两块

uv 坐标范围:0-1
这里我们需要对 uv 进行处理,思路很简单,我们把半块屏幕当作 uv 的实际坐标范围,也就是 (0 ~ 0.5) 和 (0.5 ~ 1.0)

一句代码搞定

vec2 v_uv2 = mod(v_uv * 2.0, 1.0);

效果:

看到了输出结果,这句代码不仅把左右分成了两边,上下也是,那么我们怎么处理呢?

也很简单

  • uv.y 坐标移动到中间,也就是 +0.25
  • 过滤掉多余画面
    // uv 居中
    vec2 v_uv2 = vec2(v_uv.x, v_uv.y + 0.25);
    // uv 分块
    vec2 v_uv3 = mod(v_uv2 * 2.0, 1.0);
    // 过滤画面
    if (v_uv2.y < 0.5 || v_uv2.y > 1.0 || v_uv3.x < 0.0 || v_uv3.x > 1.0 || v_uv3.y < 0.0 || v_uv3.y > 1.0) {
      discard;
    }

效果:

2. 添加 CRT 老电视效果


如果红色框是我们最开始界面,那我们的需求是:

  • uv.x 在(0 ~ 0.5)从大到小递增,在(0.5 ~ 1.0)从小到大递减
  • uv.y 在(0 ~ 0.5)从大到小递增,在(0.5 ~ 1.0)从小到大递减
    :racehorse:
vec2 post_process_crt(vec2 uv_pos_v2_, float bend_f_) {
	// -1.0 ~ 1.0
	uv_pos_v2_ = (uv_pos_v2_ - 0.5) * 2.0;

    // 缩放 uv,增加差异范围
	uv_pos_v2_ *= 1.5;

    // uv 变形
    // 由于 uv_pos_v2_.y 范围在(-1.0,1.0),所以 abs(uv_pos_v2_.y)越大则结果越大,0 为分界线
    // pow((abs(uv_pos_v2_.y) / bend_f_), 2.0) 的结果由于 abs(uv_pos_v2_.y)不会超过 1.0,所以 uv_pos_v2_.x 不会超过自己2倍
	uv_pos_v2_.x *= 1.0 + pow((abs(uv_pos_v2_.y) / bend_f_), 2.0);
	uv_pos_v2_.y *= 1.0 + pow((abs(uv_pos_v2_.x) / bend_f_), 2.0);

	// 转换回 0.0 - 1.0 空间
	uv_pos_v2_  = (uv_pos_v2_ / 2.0) + 0.5;

	return uv_pos_v2_;
}

参考图:

  • x 为 递增的 vec2, t 为递增的 number
  • 固定 y 后的 x 值
  • 固定 x 后的 y 值

3. 最终输出


至此完成我们的目标

# 结语

demogithub 链接open in new window

打开项目后请在 项目-> 项目设置 -> 项目数据 -> 更换渲染管线为 builtin-deferred2.rpp
由于目前 cocos 版本渲染管线对后处理的支持并不好, 我是修改的 web 端渲染管线实现的,所以更加推荐通过 renderTexture 方式实现。可以参考另外一篇帖子基于 renderTexture 的屏幕后期渲染|社区征文open in new window

📣 觉得很赞?分享给你的朋友吧!