用Unity开发基于Oculus Rift的体验游戏时遇到天空盒重影问题的解决方法


大家好我是天睿Tera,目前专注于开发OculusRift沉浸式体验演示项目并且在建立一个开发者交流的论坛

www.vr-x.cn


我会把在开发电梯惊魂DEMO的时候遇到的问题和怎么解决的拿出来给大家分享一下。这次分享的是解决双眼显示天空盒重影的问题。


在开发过程如果你用平常的方法加入天空盒的话,编辑器里是看不出来效果的,但当你打包运行之后会发现天空里的云是重影的。

我在Oculus官方开发者社区寻找了许久之后发现了一个Script文件SkyboxMesh.cs

把脚本贴在下面

// coded by Nora
// http://stereoarts.jp
using UnityEngine;
using System.Collections;

public class SkyboxMesh : MonoBehaviour
{
	public enum Shape {
		Sphere,
		Cube,
	}
	
	public string		shaderName	= "Unlit/Texture";
	public float		radius		= 800.0f;
	public int		 	segments	= 32;
	public Shape		shape		= Shape.Sphere;
	public Material		skybox;
	public GameObject	follow;
	
	void Awake()
	{
		Mesh mesh = _CreateMesh();
		Shader shader = Shader.Find( this.shaderName );
		_CreatePlane( mesh, shader, "_FrontTex", Quaternion.identity );
		_CreatePlane( mesh, shader, "_LeftTex",  Quaternion.Euler( 0.0f, 90.0f, 0.0f ) );
		_CreatePlane( mesh, shader, "_BackTex",  Quaternion.Euler( 0.0f, 180.0f, 0.0f ) );
		_CreatePlane( mesh, shader, "_RightTex", Quaternion.Euler( 0.0f, 270.0f, 0.0f ) );
		_CreatePlane( mesh, shader, "_UpTex",    Quaternion.Euler( -90.0f, 0.0f, 0.0f ) );
		_CreatePlane( mesh, shader, "_DownTex",  Quaternion.Euler( 90.0f, 0.0f, 0.0f ) );
	}
	
	void PostUpdate()
	{
		if( this.follow != null ) {
			this.transform.position = this.follow.transform.position;
		}
	}
	
	Mesh _CreateMesh()
	{
		Mesh mesh = new Mesh();

        int hvCount2 = this.segments + 1;
		int hvCount2Half = hvCount2 / 2;
		int numVertices = hvCount2 * hvCount2;
		int numTriangles = this.segments * this.segments * 6;
		Vector3[] vertices = new Vector3[numVertices];
        Vector2[] uvs = new Vector2[numVertices];
        int[] triangles = new int[numTriangles];
		
		float scaleFactor = 2.0f / (float)this.segments;
		float angleFactor = Mathf.Deg2Rad * 90.0f / (float)this.segments;
		float uvFactor = 1.0f / (float)this.segments;

		if( this.segments <= 1 || this.shape == Shape.Cube ) {
			float ty = 0.0f, py = -1.0f;
			int index = 0;
	        for( int y = 0; y < hvCount2; ++y, ty += uvFactor, py += scaleFactor ) {
				float tx = 0.0f, px = -1.0f;
				for( int x = 0; x < hvCount2; ++x, ++index, tx += uvFactor, px += scaleFactor ) {
					vertices[index] = new Vector3( px, py, 1.0f );
	                uvs[index] = new Vector2( tx, ty );
				}
			}
		} else {
			float ty = 0.0f, py = -1.0f;
			int index = 0, indexY = 0;
	        for( int y = 0; y <= hvCount2Half; ++y, indexY += hvCount2, ty += uvFactor, py += scaleFactor ) {
				float tx = 0.0f, px = -1.0f, py2 = py * py;
				int x = 0;
				for( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor ) {
					float d = Mathf.Sqrt( px * px + py2 + 1.0f );
					float theta = Mathf.Acos( 1.0f / d );
					float phi = Mathf.Atan2( py, px );
					float sinTheta = Mathf.Sin( theta );
	                vertices[index] = new Vector3(
						sinTheta * Mathf.Cos( phi ),
						sinTheta * Mathf.Sin( phi ),
						Mathf.Cos( theta ) );
	                uvs[index] = new Vector2( tx, ty );
				}
				int indexX = hvCount2Half - 1;
				for( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor ) {
					Vector3 v = vertices[indexY + indexX];
					vertices[index] = new Vector3( -v.x, v.y, v.z );
	                uvs[index] = new Vector2( tx, ty );
				}
			}
			indexY = (hvCount2Half - 1) * hvCount2;
	        for( int y = hvCount2Half + 1; y < hvCount2; ++y, indexY -= hvCount2, ty += uvFactor, py += scaleFactor ) {
				float tx = 0.0f, px = -1.0f;
				int x = 0;
				for( ; x <= hvCount2Half; ++x, ++index, tx += uvFactor, px += scaleFactor ) {
					Vector3 v = vertices[indexY + x];
					vertices[index] = new Vector3( v.x, -v.y, v.z );
	                uvs[index] = new Vector2( tx, ty );
				}
				int indexX = hvCount2Half - 1;
				for( ; x < hvCount2; ++x, ++index, --indexX, tx += uvFactor, px += scaleFactor ) {
					Vector3 v = vertices[indexY + indexX];
					vertices[index] = new Vector3( -v.x, -v.y, v.z );
	                uvs[index] = new Vector2( tx, ty );
				}
			}
		}
		
		{
			for( int y = 0, index = 0, ofst = 0; y < this.segments; ++y, ofst += hvCount2 ) {
				int y0 = ofst, y1 = ofst + hvCount2;
	            for( int x = 0; x < this.segments; ++x, index += 6 ) {
	                triangles[index+0] = y0 + x;
	                triangles[index+1] = y1 + x;
	                triangles[index+2] = y0 + x + 1;
	                triangles[index+3] = y1 + x;
	                triangles[index+4] = y1 + x + 1;
	                triangles[index+5] = y0 + x + 1;
	            }
	        }
		}

		mesh.vertices = vertices;
        mesh.uv = uvs;
        mesh.triangles = triangles;
		return mesh;
	}
	
	void _CreatePlane( Mesh mesh, Shader shader, string textureName, Quaternion rotation )
	{
		GameObject go = new GameObject();
		go.name = textureName;
		go.transform.parent = this.transform;
		go.transform.localPosition = Vector3.zero;
		go.transform.localScale = new Vector3( this.radius, this.radius, this.radius );
		go.transform.localRotation = rotation;
		Material material = new Material( shader );
		material.mainTexture = skybox.GetTexture( textureName );
		MeshRenderer meshRenderer = go.AddComponent< MeshRenderer >();
		meshRenderer.material = material;
		meshRenderer.castShadows = false;
		meshRenderer.receiveShadows = false;
		MeshFilter meshFilter = go.AddComponent< MeshFilter >();
		meshFilter.mesh = mesh;
	}
}

OK,有了这个脚本之后我们这样操作首先把原来的Skybox关掉

选择我们的摄影机把脚本放上去

给脚本指定一个Skybox就可以了~

这样再用Oculus Rift试一下,就不会重影了哦!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值