您的位置:首页 > 移动开发 > Unity3D

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

2014-04-14 17:45 866 查看
大家好我是天睿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试一下,就不会重影了哦!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息