3D电影的原理
今天要在unity中借用steamVR观赏3D电影,之前没有留意过3D电影相关,完全没有思路,于是先百度了一下3D电影的原理.
很久之前看过几次3D电影,那时候比较新奇,当时中途摘下过红蓝色的3D眼镜,屏幕大概是这个效果,发虚的感觉.
现在我们知道,实际上有两台放映机以一定的偏差,模仿人的双眼,把同一片源播放了两次,而3D眼镜的作用就是让左眼看其中一个影像,右眼看另外一个影像,最终我们的大脑会帮我们自动合成3D效果.
我们就以这个原理为核心,实现Unity中用VR看3D电影
实现过程
首先我们先来看看3D电影的源文件是什么样子的.
可见这部电影的片源已经有两份了,不需要我们想办法做出人眼的偏差.
但是和我们在电影院看过的3D电影好像还有些不一样.
应该是把两份片源分别拉伸到整个屏幕那么大,重叠在一起才会有发虚的效果.
于是我们先写个shader把片源拆成两份
Shader "Custom/SpitScreen" {
Properties{
_MainTex("MainText", 2D) = "white" {}//主贴图
_SpitPercentX("SpitPercentX",Range(0,1)) = 1//水平方向切割后保留的比例
_SpitPercentY("SpitPercentY",Range(0,1)) = 1//垂直方向切割后保留的比例
_SpitOffsetX("SpitOffsetX",Range(0,1)) = 0//水平方向裁剪区的偏移量
_SpitOffsetY("SpitOffsetY",Range(0,1)) = 0//垂直方向裁剪区的偏移量
}
SubShader{
LOD 200
Tags{ "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
fixed _SpitPercentX;
fixed _SpitPercentY;
fixed _SpitOffsetX;
fixed _SpitOffsetY;
struct Input {
float2 uv_MainTex;
};
void surf(Input IN, inout SurfaceOutput o) {
float2 uv = IN.uv_MainTex;
fixed4 tex = tex2D(_MainTex, float2(uv.x*_SpitPercentX + _SpitOffsetX, uv.y*_SpitPercentY + _SpitOffsetY));//解析贴图
o.Albedo = tex.rgb;//计算漫反射颜色
}
ENDCG
}
FallBack "Standard"
}
我们修改参数就可以取左边或者右边的一半.(写好之后发现表面着色器自带缩放和偏移,Tiling和offset的效果和上面的代码是完全一致的)
通过这个shader我们可以把片源的两个影像拆分出来了.
接下来我们创建两个material改变参数,让两块屏幕分别显示左半部分和右半部分,然后把两个屏幕的position改成一样的
为两块屏幕设置不同的层,名字随便取,目的是让相机分别过滤掉另一个屏幕,模仿3D眼镜的原理.左眼看不见右屏幕,右眼看不见左屏幕.
然后创建两个相机,分别对应左右眼,过滤掉另一块屏幕(我把MainCamera做成了右眼相机)
至此,3D电影就改造完毕了,steamVR的SDK会识别到标记为左右眼的相机,并且把相机渲染的图像输出给头盔的左右眼.
如何在Unity中播放一段视频不在本篇讨论范围内,我个人是使用了AVpro的插件来播放视频.
至于是什么效果.编辑器里是看不到了,需要一个VR头盔才行,个人觉得和在电影院看到的3D电影是同样的效果.
最后感叹一下,还是人类的大脑NB,自动合成3D影像