[muzzik教程]:VR 后处理效果 | 社区征文

# 前言

相信当年VR刚出的时候大家都体验过吧?这里就用 cocos 的后处理来实现 VR 效果

从其他的 VR 应用可以看出来,手机 VR 画面是由 左右两个相同的类似老电视机画面组成 的(其实是我没找到关于手机 VR 展示的资料…)

那么就从这里入手,去逛了下 shadertoy,果然找到一个类似的 效果,然后搬到了 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);

效果:
)1W8({U7$1F~X~QZ5Q0M`C

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

  • 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;
    }

效果:
E)RU@JFLZ0WBH`{~N81L
不戳不戳有那味了~

2. 添加 CRT 老电视效果

W{1TT7YSM4@JBWLI3C~CQPP

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

  • 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_;
}

参考图:

3. 最终输出

S8CL9@%}9MYBF{K5IF$7

至此完成我们的目标, 下班前赶稿,写的不好见谅

# 结语

demogithub链接
打开项目后请在 项目-> 项目设置 -> 项目数据 -> 更换渲染管线为 builtin-deferred2.rpp

由于目前 cocos 版本渲染管线对后处理的支持并不好, 我是修改的 web 端渲染管线实现的,所以更加推荐通过 renderTexture 方式实现。可以参考另外一篇帖子

5赞

膜拜大佬~
学习学习

66666666666666666666!