如何使用unity3D做一个360°的图像查看器

这篇文章包含了从如何创建一个图像查看器到如何在unity5.3.3使用鼠标控制它。

概括地说,下面的过程是使用自定义的shader创建一个材质和应用在球体上的一幅图片。让我们使用一些小技巧从这幅图片开始吧。

第1步:准备一张合适的图片

在查看器中使用的图片必须是2:1的宽高比和球面投影,这意味着为了正确地在球体内渲染,图片的顶部和底部必须是拉伸的。

球面投影如果图片具有更全景式的宽长比,当我们创建一个放置在球体上的材质时将显得更加约束。于我而言,这是我使用的测试图片

第2步:创建shader

现在我们需要创建一个自定义的shader,这个shader会改变材质在球体内部的投射而不是改变其在球体外部的投射,正是由于这一点,应用镜像图像不会使之看得有偏差。这是我的shader代码:

Shader “Unlit/Pano360Shader”
{
   Properties
   {
       _MainTex (“Base (RGB)”, 2D) = “white” {}
       _Color (“Main Color”, Color) = (1,1,1,0.5)
   }
   SubShader 
   {
      Tags { “RenderType” = “Opaque” }
      //This is used to print the texture inside of the sphere
      Cull Front
      CGPROGRAM
      #pragma surface surf SimpleLambert
      half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten)
      {
         half4 c;
         c.rgb = s.Albedo;
         return c;
      }
       
      sampler2D _MainTex;
      struct Input
      {
         float2 uv_MainTex;
         float4 myColor : COLOR;
      };
  
      fixed3 _Color;
      void surf (Input IN, inout SurfaceOutput o)
      {
         //This is used to mirror the image correctly when printing it inside of the sphere
         IN.uv_MainTex.x = 1 — IN.uv_MainTex.x;
         fixed3 result = tex2D(_MainTex, IN.uv_MainTex)*_Color;
         o.Albedo = result.rgb;
         o.Alpha = 1;
      }
      ENDCG
   }
   Fallback “Diffuse”
}

第3步:创建球体并设置摄像机

创建一个包含摄像机的游戏对象,也就是说摄像机作为cameraContainer游戏对象的子对象。这个cameraContainer游戏对象必须放置在球体的中间,像这样:

第4步:创建材质并应用到球体上
使用之前创建的shader来创建并应用材质,并且附加上图片,它将像这样:

试着在球体内部移动并观察图像:

正如你看到的那样,建筑物有一点扭曲,我把材质y tiling的值从1改成1.15,解决了这个问题,如果图像的球面投影不恰当就有可能出现这个问题。

现在建筑物看起来就比较好了。

第5步:增加鼠标控制使得在球体内部移动
你需要创建一个脚本,根据鼠标的位置来控制摄像机的旋转,如下是附加在摄像机上的脚本:

float horizontal;
float vertical;
Transform container;
void LateUpdate ()
{
    //Using mouse
    horizontal = Input.GetAxis(“Mouse X”);
    vertical= Input.GetAxis(“Mouse Y”);
  
    //This is made in order to avoid rotation on Z, just by typing 0 on Zcoord isn’t enough
    //so the container is rotated around Y and the camera around X separately
    container.Rotate(new Vector3(0,horizontal*(-1),0f)*Time.deltaTime*turnSpeedMouse);
    transform.Rotate(new Vector3(vertical, 0, 0)*Time.deltaTime*turnSpeedMouse);
}

标签: none

?>